Laskennan perusmallit (LAP)



Samankaltaiset tiedostot
1 Kurssin asema opetuksessa

Esimerkki 1: Kahviautomaatti.

Laskennan mallit

Laskennan teoria

Laskennan teoria

5.3 Ratkeavia ongelmia

Todistus: Aiemmin esitetyn mukaan jos A ja A ovat rekursiivisesti lueteltavia, niin A on rekursiivinen.

Täydentäviä muistiinpanoja laskennan rajoista

Esimerkkejä polynomisista ja ei-polynomisista ongelmista

on rekursiivisesti numeroituva, mutta ei rekursiivinen.

Rajoittamattomat kieliopit (Unrestricted Grammars)

Kielenä ilmaisten Hilbertin kymmenes ongelma on D = { p p on polynomi, jolla on kokonaislukujuuri }

Muodolliset kieliopit

Pysähtymisongelman ratkeavuus [Sipser luku 4.2]

M = (Q, Σ, Γ, δ, q 0, q acc, q rej )

Lisää pysähtymisaiheisia ongelmia

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti

Chomskyn hierarkia. tyyppi 0 on juuri esitelty (ja esitellään kohta lisää) tyypit 2 ja 3 kurssilla Ohjelmoinnin ja laskennan perusmallit

Muita vaativuusluokkia

Chomskyn hierarkia ja yhteysherkät kieliopit

Rekursiiviset palautukset [HMU 9.3.1]

Automaatit. Muodolliset kielet

Output. Input Automaton

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

ICS-C2000 Tietojenkäsittelyteoria Kevät 2016

Tarkastelemme ensin konkreettista esimerkkiä ja johdamme sitten yleisen säännön, joilla voidaan tietyissä tapauksissa todeta kielen ei-säännöllisyys.

TKT20005 Laskennan mallit (syksy 2018) Kurssikoe, malliratkaisut

} {{ } kertaa jotain

(0 1) 010(0 1) Koska kieli on yksinkertainen, muodostetaan sen tunnistava epädeterministinen q 0 q 1 q 2 q3

Kurssikoe on maanantaina Muista ilmoittautua kokeeseen viimeistään 10 päivää ennen koetta! Ilmoittautumisohjeet löytyvät kurssin kotisivuilla.

Äärellisten automaattien ja säännöllisten kielten ekvivalenssi

8. Kieliopit ja kielet 1 / 22

FUNKTIONAALIANALYYSIN PERUSKURSSI Johdanto

1. Universaaleja laskennan malleja

Säännöllisen kielen tunnistavat Turingin koneet

Algoritmit 1. Luento 2 Ke Timo Männikkö

uv n, v 1, ja uv i w A kaikilla

Laskennan teoria (kevät 2006) Harjoitus 3, ratkaisuja

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 31. maaliskuuta 2011

Aloitus. TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 14. maaliskuuta 2011 TIETOTEKNIIKAN LAITOS. Aloitus.

4.3. Matemaattinen induktio

2. Laskettavuusteoriaa

Automaattiteoria diskreetin signaalinkäsittelyn perusmallit ja -menetelmät ( diskreettien I/O-kuvausten yleinen teoria)

Se mistä tilasta aloitetaan, merkitään tyhjästä tulevalla nuolella. Yllä olevassa esimerkissä aloitustila on A.

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 31. maaliskuuta 2011

Johdatus Ohjelmointiin

Epädeterministisen Turingin koneen N laskentaa syötteellä x on usein hyödyllistä ajatella laskentapuuna

Matematiikan mestariluokka, syksy

2. Laskettavuusteoriaa

LUKU II HOMOLOGIA-ALGEBRAA. 1. Joukko-oppia

Luonnolliset vs. muodolliset kielet

Ohjelmoinnin perusteet Y Python

Topologia Syksy 2010 Harjoitus 9

TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 3. joulukuuta 2015

Säännöllisten kielten sulkeumaominaisuudet

811120P Diskreetit rakenteet

Matematiikan tukikurssi

Laskennan rajoja. TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 10. joulukuuta 2015 TIETOTEKNIIKAN LAITOS.

Algoritmin määritelmä [Sipser luku 3.3]

Vastauksia. Topologia Syksy 2010 Harjoitus 1

TIEA241 Automaatit ja kieliopit, kevät Antti-Juhani Kaijanaho. 8. maaliskuuta 2012

Vastaus 1. Lasketaan joukkojen alkiot, ja todetaan, että niitä on 3 molemmissa.

Miten perustella, että joukossa A = {a, b, c} on yhtä monta alkiota kuin joukossa B = {d, e, f }?

Ongelma(t): Mikä on Turingin kone? Miten Turingin kone liittyy funktioihin ja algoritmeihin? Miten Turingin kone liittyy tietokoneisiin?

Injektio. Funktiota sanotaan injektioksi, mikäli lähtöjoukon eri alkiot kuvautuvat maalijoukon eri alkioille. Esim.

ITKP102 Ohjelmointi 1 (6 op)

T Syksy 2004 Logiikka tietotekniikassa: perusteet Laskuharjoitus 7 (opetusmoniste, kappaleet )

Kertausta 1. kurssikokeeseen

TIEA241 Automaatit ja kieliopit, kevät 2011 (IV) Antti-Juhani Kaijanaho. 19. tammikuuta 2012

vaihtoehtoja TIEA241 Automaatit ja kieliopit, syksy 2016 Antti-Juhani Kaijanaho 13. lokakuuta 2016 TIETOTEKNIIKAN LAITOS

8. Kieliopit ja kielet

Vaihtoehtoinen tapa määritellä funktioita f : N R on

Hahmon etsiminen syotteesta (johdatteleva esimerkki)

Täydentäviä muistiinpanoja Turingin koneiden vaihtoehdoista

Rekursio. Funktio f : N R määritellään yleensä antamalla lauseke funktion arvolle f (n). Vaihtoehtoinen tapa määritellä funktioita f : N R on

Algoritmit 1. Luento 13 Ti Timo Männikkö

Tietorakenteet (syksy 2013)

etunimi, sukunimi ja opiskelijanumero ja näillä

Turingin koneet. Sisällys. Aluksi. Turingin koneet. Turingin teesi. Aluksi. Turingin koneet. Turingin teesi

Tietotekniikan valintakoe

Esitetään tehtävälle kaksi hieman erilaista ratkaisua. Ratkaisutapa 1. Lähdetään sieventämään epäyhtälön vasenta puolta:


TIEA241 Automaatit ja kieliopit, syksy Antti-Juhani Kaijanaho. 5. marraskuuta 2015

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

3. Laskennan vaativuusteoriaa

Johdatus matemaattiseen päättelyyn

Laskennan rajoja. TIEA241 Automaatit ja kieliopit, kesä Antti-Juhani Kaijanaho. 20. kesäkuuta 2013 TIETOTEKNIIKAN LAITOS.

1. Esitä rekursiivinen määritelmä lukujonolle

Laskennan mallit (syksy 2010) Harjoitus 4, ratkaisuja

4. Tehtävässä halutaan todistaa seuraava ongelma ratkeamattomaksi:

Laskennan vaativuus ja NP-täydelliset ongelmat

Yhteydettömän kieliopin jäsennysongelma

Satunnaisalgoritmit. Topi Paavilainen. Laskennan teorian opintopiiri HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos

Algoritmit 1. Luento 11 Ti Timo Männikkö

Laskennan mallit (syksy 2008) 2. kurssikoe , ratkaisuja

9. Matemaattisista koneista.

Pinoautomaatit. TIEA241 Automaatit ja kieliopit, kesä Antti-Juhani Kaijanaho. 6. kesäkuuta 2013 TIETOTEKNIIKAN LAITOS. Pinoautomaatit.

Säännölliset kielet. Sisällys. Säännölliset kielet. Säännölliset operaattorit. Säännölliset kielet

TIEA241 Automaatit ja kieliopit, kesä Antti-Juhani Kaijanaho. 29. toukokuuta 2013

Transkriptio:

Laskennan perusmallit (LAP) Pekka Kilpeläinen Tietojenkäsittelytieteen laitos, Itä-Suomen yliopisto sähköposti: pekka.t.kilpelainen@uef.fi Lukuvuosi 2013 14, III periodi

Kurssin asema opetuksessa Tietojenkäsittelytieteen pääaineopiskelijoille pakollinen aineopintokurssi (3 op). Esitietovaatimukset: Johdatus tietojenkäsittelytieteeseen (JTT): Laskennan, algoritmin ja tietokoneen käsitteet. Diskreetit rakenteet (DSR): Sovelletaan diskreetin matematiikan peruskäsitteitä, kuten joukkoja, relaatioita, funktioita, puita ja verkkoja. Lisäksi molemmilla kursseilla lähestymistapa ja ajatusmaailma on matemaattinen (eikä esimerkiksi ohjelmointitekninen). Tietorakenteet 1 (TRA1): Käytetään joitakin siellä selostettuja perustietorakenteita, kuten pinoja ja puita. Lisäksi viitataan joihinkin siellä esiteltyihin käsitteisiin, kuten asymptoottiseen aikavaativuuteen.

Kiinnostuneille lisää valinnaisilla syventävien opintojen jatkokursseilla: Algoritmien suunnittelu ja analyysi (ASA): Tätä kurssia laajemmat perustiedot ns. P? = NP-ongelmasta sekä teoreettisesta että algoritmisuunnittelun näkökulmasta. Laskennan teoria (LAT): Syvällisemmin tästä ongelmasta ja muistakin tällä kurssilla esitellyistä asioista.

Tämä P? = NP-ongelma onkin tunnetuin esimerkki laskennan vaativuusteorian käsittelemistä ongelmista. Yksi (mutta ei läheskään ainoa!) tapa lukea se on: P = sellaiset laskentaongelmat, joiden vastaukset voi laskea tavallisella tietokoneella tehokkaasti NP = voisi jos koneeseen lisättäisiin maaginen konekäsky valitse hyppäätkö nyt riville X vaiko riville Y joka jotenkin aina osaisi valita juuri oikein. Silloin kysymys on: Voisiko tavallinen tietokone aina löytää itsekin oikean valinnan nopeasti? Yleisesti uskotaan, että ei voisi: Uskotaan, että on sellaisia ongelmia ja tilanteita, joissa on väistämättä hidasta löytää se oikea valinta.

Tämä P? = NP-ongelma on kuitenkin osoittautunut teoriassa hyvin vaikeaksi ratkaista se on yhä avoin, ja on saatu tuloksia ainakaan menetelmällä X sitä ei voi ratkaista erilaisille lähestymistavoille X. käytännössä merkittäväksi, koska monet käytännön ongelmat ovat osoittautuneet ns. NP-vaikeiksi, eli sellaisiksi että jos yksikin niistä voitaisiin ratkaista tehokkaasti (eli se kuuluisi luokkaan P) niin sen avulla ne kaikki muutkin voitaisiin ratkaista tehokkaasti. Clay Mathematics Institute onkin valinnut sen yhdeksi seitsemästä Millennium-ongelmastaan, ja antaa sen ratkaisusta palkinnoksi 1 000 000 USD! (http://www.claymath.org/millennium/) Jo tietojenkäsittelijän yleissivistykseen kuuluu tuntea peruskäsitteet kuten laskentaongelma jne., ja tämän kurssin tavoitteena onkin tutustuttaa niihin.

Kurssin suorittaminen Luennot: Harjoitukset: 2 + 2 tuntia viikossa, yhteensä 22 tuntia. Videoidaan Kuopion kampukselta. 2 tuntia viikossa, yhteensä 5 viikkoa. 20% kurssin pisteistä tulee tehdyistä laskuharjoituksista lineaarisesti. Tehtävät tulevat Wikiin edellisen viikon aikana. Luentokuulustelu ja sen uusintakuulustelu: Loput 80% kurssin pisteistä. Koealue: ne asiat, joita on käsitelty luennoilla tai harjoituksissa. Arvostelu: Alimpaan hyväksyttyyn arvosanaan 1/5 vaaditaan vähintään 50% kokonaispisteistä, korkeimpaan 5/5 vähintään 90%, ja muut lineaarisesti. Niiden jälkeiset yleiset tentit: Koealue käsittää vain luennot ja arvostelussa huomioidaan vain koepisteet. Harjoituksia ei enää huomioida.

Oppimateriaali Nämä luentomuistiinpanot ovat wikissä: http://wiki.uef.fi tkt-wiki Kurssien kotisivuja - Course homepages LAP - Laskennan perusmallit (3621317, 3op). Pohjautuvat Kimmo Fredrikssonin ja Matti Nykäsen luentoihin edellisiltä vuosilta. Pelkät muistiinpanot eivät välttämättä riitä itseopiskeluun, vaan voivat vaatia tuekseen joko luentojen tai jonkun oppikirjan seuraamista. Esimerkiksi kirjan Hopcroft, John E., Motwani, Rajeev ja Ullman, Jeffrey D.: Introduction to Automata Theory, Languages and Computation, 2. painos (Addison Wesley, 2001) luvut 1 8.2, 9 9.3 ja 10 kattavat valtaosan kurssin asioista (näitä luentoja yksityiskohtaisemmin).

Kurssin asema tietojenkäsittelytieteessä Erään määritelmän mukaan tietojenkäsittely tutkii 1. millaiset tietojenkäsittelytehtävät on mahdollista automatisoida ja 2. miten tämä automatisointi tulisi suorittaa. Useimpien kurssien lähestymistapa on yleensä konstruktiivinen, eli kohta 2. Esimerkiksi TRA: Kehitetään annetun laskentaongelman tehokkaasti ratkaiseva algoritmi ja sen tarvitsemat tietorakenteet. Tällä kurssilla painoalue onkin kohdassa 1. Osoittautuu, että on olemassa erilaisia tehtäviä; sellaisia 1. joita ei edes periaatteessa voi automatisoida algoritmin olemassaolo on looginen mahdottomuus. 2. jotka voi automatisoida, mutta vain tehottomasti tehokasta algoritmia ei voi olla olemassa. 3. jotka voi automatisoida ja tehokkaasti tehokaskin algoritmi on keksitty: luokka P. 4. joista emme vielä tiedä ovatko ne tehokkaasti ratkaistavissa vai aidosti työläitä; erityisesti päteekö NP P?

Historiaa Laskentaongelman käsitteen muotoilu sekä ongelmien erottelu automatisoitumattomiin (eli tyyppiin 1) ja automatisoituviin tehtiin 1930-luvulla. Siis jo ennen tietokoneita! (Ensimmäiset yleiskäyttöiset tietokoneet rakennettiin pian II maailmansodan jälkeen.) Motivaationa oli matematiikan filosofian ja formaalin logiikan kehitys: Haluttiin erottaa toisistaan sellaiset matemaattiset ja loogiset ongelmat, jotka vaativat aitoa luovuutta, sellaisista joihin riitti pelkkä laskeminen...... siis antaa tarkka formaali määritelmä arkikielen käsitteelle mekaaninen laskenta. Näin syntyi laskettavuuden teoria yhdeksi keskeiseksi osaksi matemaattista logiikkaa.

Tällä kurssilla esitetään mekaaniselle laskennalle tarkka formaali määritelmä käyttäen ns. Turingin koneita tietokonepioneeri Alan M. Turingin vuonna 1936 esittämää abstraktia matemaattista mallia hypoteettiselle laskulaitteelle. Samaan aikaan oli muitakin loogikkojen ehdotuksia mekaanisen laskennan määritelmäksi, esimerkiksi: Kurt Gödel kehitti 1930-luvun alusta alkaen rekursiivisten funktioiden teoriaa osana kuuluisan (ensimmäisen) epätäydellisyyslauseensa todistusta. Ideana oli induktio: funktion seuraava arvo f (n + 1) voidaan määritellä edellisen arvon f (n) avulla, jossa n N. Alonzo Church esitti vuonna 1936 oman λ-laskentansa. Ideana oli laskenta lausekkeen sievennyksenä. Nämä taas olivat tärkeitä ohjelmoinnin ja ohjelmointikielten kehitykselle. Tällä kurssilla niitä ei käsitellä, mutta kurssilla Johdatus funktionaaliseen ohjelmointiin (FOH) sivutaan λ-laskentaa.

Miksi valittiin Turingin laitelähtöinen lähestymistapa mekaanisen laskennan määritelmäksi eikä Gödelin tai Churchin ohjelmointilähtöistä? Eksplisiittinen laite joka kulkea raksuttaa kuin kello on konkreettisempi käsite kuin induktio tai sievennys joiden voisi epäillä sittenkin vaativan sitä aitoa luovuutta... Laskentaan kuluva aika ja tila on helpompi määritellä laitteen kuin siinä pyörivän ohjelman kautta. Tietokoneiden yleistymisen myötä alettiin huomata, että tämä mekaaninen laskenta jakautui edelleen vaivalloiseen (eli tyypin 2) ja vaivattomaan (eli tyypin 3) mekaaniseen laskentaan. Yksi tapa selventää tätä jakoa on tutkia vielä yksinkertaisempia laskulaitteita kuin Turingin kone. Tätä automaattien teoriaa on kehitetty 1960-luvulta lähtien. Tällä kurssilla tutustummekin sen keskeisiin käsitteisiin kuten äärellisiin ja pinoautomaatteihin. Toinen tapa on asettaa resurssirajoja Turingin koneille. Tätä laskennan vaativuusteoriaa on kehitetty 1970-luvulta lähtien. Sen keskeinen ongelma on juuri edellä mainittu P? = NP. Vaativuusteoria kuitenkin jätetään valtaosin kursseille ASA ja LAT.

Kurssin sisältö tästä eteenpäin 1. Johdanto: Yleiskatsaus laskennan teoriaan, laskennan vaativuusteoriaan ja laskennan malleihin. Kurssilla käytettävien käsitteiden ja notaatioiden määritelmiä. 2. Säännölliset kielet: äärelliset automaatit ja säännölliset lausekkeet. Äärelliset automaatit ovat mahdollisimman yksinkertaisia laskulaitteita. Säännölliset kielet taas ovat sellaisia merkkijonojoukkoja, joihin kuuluminen voidaan ratkaista näillä laitteilla. Säännölliset lausekkeet taas ovat notaatio, jolla niitä voidaan kuvata lyhyesti. Kun esimerkiksi kirjoitat Linuxin komentoriville ls *.jar niin käytät säännöllistä lauseketta *.jar kuvailemaan säännöllisen kielen kaikki sellaiset ASCII-merkkijonot, jotka päättyvät merkkijonoon.jar ja kone listaa sinulle kaikki ne tämän hakemiston tiedostonimet, jotka tämän kielen tunnistava automaatti hyväksyy sen jäseniksi. Käytännössä niihin törmää esimerkiksi merkkijonoalgoritmeissa, hajautettujen järjestelmien mallintamisessa sekä dokumenttirakenteiden kaaviokielissä (kuten XML DTD ja XML Schema).

3. Kontekstittomat kielet ja kieliopit sekä pinoautomaatit. Vastaavasti pinoautomaatit ovat hieman mutkikkaampia laskulaitteita ja kontekstittomat kielet niitä, joita ne voivat tunnistaa. Ne ovat käytännössä tärkeitä rakenteisen syötteen käsittelyssä. Esimerkiksi HTML, XML sekä rakenteisella ohjelmointikielellä kirjoitettu lähdekoodi ovat rakenteisia syötteitä, koska niissä on mielivaltaisen mutkikkaita sisäkkäisyyksiä, joista syötettä lukevan ohjelman pitää ottaa selvää. Esimerkiksi HTML-syötettä lukevan ohjelman pitää löytää korostuksen aloittavalle tagille <em> juuri oikea sitä vastaava lopettava tag </em>, ja niiden välissä voi olla muita senkaltaisia tagipareja, jotka pitää samoin parittaa. Kontekstittomat kieliopit taas ovat näiden kielten kuvailutapa, vastaavasti kuin säännölliset lausekkeet ovat säännöllisille kielille. Laskettavuuden ja varsinkaan laskennan vaativuuden teoriaa emme valitettavasti ennätä käsitellä juuri lainkaan. Laskennallisesti vaativiin tai jopa kokonaan ratkeamattomiin ongelmiin törmää esimerkiksi tekoälyssä sekä ohjelmien ja järjestelmien formaalissa verifioinnissa.

Oikeaa palautetta... Kaikenkaikkiaan mielenkiintoinen kurssi, kunhan selvisi ensimmäisen luennon alkujärkytyksestä, joka asian puolesta tuntui sellaiselta ettei tästä selviä millään keinoin. Mutta onneksi sitä ei heti tullut tiputettua rukkasia, sillä kurssin edetessä asiat alkoivat selkiintymään ja niitä jopa ymmärtääkin (paljon jäi vielä opittavaksi)... Anonyymi opiskelija, kevät 2009

Johdanto I Laskennan teoria (theory of computation) käsittelee sitä, miten ongelma luokitellaan ratkeavuuden, vaikeuden ja tehokkuuden perusteella ennen kuin se ratkaistaan. Se jaetaan perinteisesti kahteen osa-alueeseen: Laskettavuuden teoria (theory of computability) tutkii, mitä tietokoneella ylipäänsä voidaan ratkaista ja kuinka vaikea annettu ongelma on. Ongelmien vaikeus määritellään melko karkealla tasolla sen perusteella, kuinka monimutkaista laskennan mallia ratkaisussa tarvitaan. Lisäksi laskettavuuden teoria antaa hyviä eväitä itse ratkaisun laatimiseen. (LAP, LAT)

Johdanto II Laskennan vaativuusteoria (theory of computational complexity) tutkii, kuinka tehokkaasti ongelma voidaan ratkaista. Laskennan vaativuusteoria muistuttaa algoritmien analyysia, mutta siinä ei määritellä yksittäisen ratkaisualgoritmin aika- tai tilavaativuutta, vaan itse ongelman pahimman tapauksen aika- ja tilavaativuusluokka. Laskennan vaativuusteoria antaa myös hyvät eväät ongelmien palauttamiseksi toisiin, jo tunnettuihin ongelmiin. (LAT, ASA)

Tällä kurssilla käsitellään jonkin verran laskennan teorian ensimmäistä osa-aluetta eli laskettavuuden teoriaa. Aihepiirinä ovat laskennalliset ongelmat ja niiden ratkaisun mekaaniset mallit, joita kutsutaan laskennan malleiksi. Käsittelemme kahta eri laskennan mallia äärellisiä automaatteja ja pinoautomaatteja sekä tutkimme, mitä kullakin mallilla voidaan ratkaista. Kurssin loppupuolella esitellään lyhyesti myös Turingin koneet (joista enemmän kurssilla LAT).

Laskettavuuden teoriasta Laskennan mekaaninen malli, automatisointi, tarkoittaa tämän kurssin kannalta algoritmin esittämistä. Intuitiivisesti algoritmi kuvaa tietojenkäsittelyprosessin niin täsmällisesti, että se voidaan tämän kuvauksen perusteella suorittaa mekaanisesti (ilman luovaa ajattelua ). Mekaanisen laskennan tarkemmaksi määrittelemiseksi, eli algoritmikäsitteen matemaattiseksi formalisoimiseksi, on kaksi lähestymistapaa: 1. Lähdetään liikkeelle tyhjästä ja mietitään, mitä voidaan pitää mekaanisena laskentana. 2. Otetaan lähtökohdaksi nykyiset tietokoneet, jotka selvästi suorittavat mekaanista laskemista, ja pelkistetään pois epäolennaisuudet.

Koska mekaaninen laskenta on keskeistä matematiikan perusteiden tarkastelussa, matemaatikot ja loogikot miettivät asiaa paljon 1930-luvulla. He sovelsivat luonnollisesti lähestymistapaa 1 koska tietokoneita ei silloin vielä ollut. Jos taas halutaan soveltaa tuloksia käytännön tietojenkäsittelyyn, lähestymistapa 2 tuntuisi lupaavammalta. Tämä on oleellisesti se tapa, jota käytettiin esimerkiksi kurssilla TRA, kun siellä laskettiin asymptoottisia resurssitarpeita eli O-arvioita. Onneksi osoittautuu, että lähestymistavat 1 ja 2 johtavat samaan algoritmikäsitteen formalisointiin. Siis matemattista logiikkaa ja tietokoneita koskevilla periaatteellisilla rajoituksilla on syvällinen yhteys. Laskettavuuden teoria tarkastelee näitä rajoituksia, eli sitä millaisille ongelmille on olemassa ratkaisualgoritmi.

Automaattiteoria Kun on saatu valmiiksi abstrakti malli tietokoneelle, voidaan kysyä, mikä muuttuu, jos mallista jätetään jokin piirre pois. Rajoitettujen mallien tarkasteleminen auttaa ymmärtämään yleisempiä malleja. Äärellinen automaatti on hyvin yksinkertainen (abstrakti) laskentalaite, jolla kuitenkin voi tehdä mielenkiintoisia asioita. Teoreettisen mielenkiinnon lisäksi se on hyödyllinen käytännössä ohjelmointi- ja mallinnustekniikkana. Kontekstittomat kieliopit ovat hieman äärellisiä automaatteja ilmaisuvoimaisempi mekanismi, jolla on tärkeitä sovelluksia esimerkiksi ohjelmointikielten määrittelemisessä ja kääntämisessä ja luonnollisen kielen mallintamisessa.

Laskennalliset ongelmat Laskennallinen ongelma = mikä tahansa tehtävä, joka voidaan mallintaa ratkaistavaksi digitaalisella tietokoneella. Laskennallisia ongelmia: kokonaislukujen kertolasku kirjastokortiston aakkostaminen yrityksen palkanlaskenta yliopistollisen kurssin kurssitietojen ylläpito annetun kokonaislukulistan järjestäminen... Ongelman ratkaiseva ohjelma on sen yksi esitystapa.

ONGELMA LASKENNALLINEN ONGELMA EI LASKENNALLINEN ONGELMA RATKEAVA ONGELMA RATKEAMATON ONGELMA TEHOKKAASTI RATKAISTAVISSA TEHOKASTA RATKAISUA EI OLE MISSÄ NÄIDEN VÄLINEN RAJA KULKEE? OSITTAIN RATKEAVA TÄYSIN RATKEAMATON (useita eri asteita) Kuva : Ongelmien hyvin karkea luokittelu

Mihin sijoittuu ongelma Onko oikein huijata tentissä? Jos mielestäsi tentissä huijaaminen on kaikissa olosuhteissa väärin, niin silloin ongelma on triviaalisti laskennallinen ja tehokkaasti ratkaistavissa: Tietenkin voidaan kirjoittaa ohjelma, joka ei lue syötettään, vaan tulostaa heti Ei!. Jos taas mielestäsi tentissä huijaaminen voi olla oikein joissakin lieventävissä olosuhteissa niin silloin on mietittävä jatkokysymystä Voiko nämä olosuhteet kuvailla tyhjentävästi sanallisesti?

Jos mielestäsi näiden olosuhteiden kaikki relevantit aspektit voi kuvailla vaikkapa jollakin sopivalla logiikalla, niin silloin ongelma on laskennallinen: Jos olosuhteet ovat kuten tämä kaava φ kuvailee, niin onko silloin oikein huijata tentissä vaiko ei? Tämä φ on se syöte, joka luetaan, ja jonka perusteella ratkaistaan onko vastaus Kyllä! vaiko Ei!. Ongelma on ratkeava, jos tämä käytetty logiikka on riittävän yksinkertainen; muuten ratkeamaton. Esimerkiksi lauselogiikka on ratkeava, predikaattilogiikka ratkeamaton. Vaikka ongelma olisikin ratkeava, se tuskin on tehokkaasti ratkaistavissa; looginen päättely on yleensä työlästä tietokoneellekin. Esimerkiksi lauselooginen päättely on NP-vaikeaa eli luultavasti työlästä.

Jos taas katsot todellisuuden olevan niin monimutkainen ja hienosyinen, että on mahdotonta kuvailla loogisesti kaikkia tällaiseen moraaliseen päätöksentekoon vaikuttavia aspekteja, niin silloin ongelma ei ole laskennallinen: Silloin meillä ei ole riittävän ilmaisuvoimaista kieltä jolla voisimme kuvailla olosuhteet riittävän kattavasti ja tarkasti syötekaavaksi φ. Siis algoritminen tietojenkäsittely eli laskenta on oleellisesti syntaktista manipulointia.

Ongelman esitys Laskennallinen ongelma = kuvaus äärellisesti esitettävien tapausten joukosta äärellisesti esitettävien vastausten joukkoon Ongelmalla on potentiaalisesti ääretön joukko tapauksia ( syötteitä ). Ongelman ratkaisu on algoritmi, joka liittää kuhunkin tapaukseen sen oikean vastauksen ( tulosteen ). Jokaisen yksittäisen tapauksen ja sen vastauksen on oltava äärellisesti esitettäviä (muutenhan laskenta ei päättyisi). Esimerkki Kokonaislukujen kertolaskuongelmassa tapauksia ovat kaikki kokonaislukuparit (p, q) (merkkijonoiksi koodattuna) vastaus annetulle tapaukselle on kyseisen lukuparin tulo p q (merkkijonoksi koodattuna) ratkaisu on mikä tahansa yleinen kertolaskualgoritmi (esimerkiksi koulussa opittu alakkain laskeminen ).

Syötteet Tulosteet π (1,1) (1,3)... (2,2) (2,4)... (1,2) (2,3) jne. 1 3 4 8... 2 6 Kuva : Kertolaskuongelman syötteet ja tulosteet.

Äärellinen esitys Kaikki tietokoneen käsittelemä tieto täytyy viime kädessä koodata bittijonoiksi. On luontevaa sallia koodaukseen käytettävän myös muita merkkejä kuin bitit 0 ja 1 (koska nämä muut merkit voidaan tietenkin tarvittaessa edelleen esittää bittijonoina). Määritelmä: äärellinen esitys = äärellisen pituinen merkkijono (eli jono merkkejä) jossakin äärellisessä aakkostossa.

Peruskäsitteitä: Aakkosto Aakkosto on äärellinen, epätyhjä joukko alkeismerkkejä eli symboleita. Esimerkiksi binääriaakkosto B = {0, 1} ja latinalainen aakkosto {A, B, C,..., Z}. Aakkosto voidaan määritellä ihan miten halutaan, esim: {HiiriVasenNappi, HiiriOikeaNappi, HiiriKeskiNappi, HiiriRullaYlös, HiiriRullaAlas}.

Peruskäsitteitä: Merkkijonot Merkkijono (eli sana) on äärellinen järjestetty jono jonkin aakkoston merkkejä. Esim. 01001 ja 000 ovat binääriaakkoston B merkkijonoja, ja LAP ja XYZZY ovat latinalaisen aakkoston merkkijonoja. Merkintä Σ tarkoittaa kaikkien niiden merkkijonojen joukkoa, jotka voidaan muodostaa annetun aakkoston Σ eli merkkien merkeistä. Siis B = {ε, 0, 1, 00, 01, 10, 11, 000,... }. Tyhjä merkkijono ε ei sisällä yhtään merkkiä. (Huom! Eri asia kuin välilyönti ). Merkkijonon x pituus x on siihen sisältyvien merkkien määrä. Esim. 01001 = XYZZY = 5 ja ε = 0.

Merkkijonojen katenointi ja kääntäminen Katenaatio on merkkijonojen kirjoittamista peräkkäin, esimerkiksi: jos x = 00 ja y = 11, niin xy = 0011 ja yx = 1100; kaikilla x on xε = εx = x; kaikilla x ja y on xy = x + y. Toisto eli merkkijonon katenaatio itsensä kanssa voidaan merkitä potenssina: a 3 = aaa (ab 2 ) 3 = (abb) 3 = abbabbabb. Itse asiassa merkintä (...) voidaankin lukea toisto mielivaltaisen (mutta äärellisen) monta kertaa. Käänteismerkkijono x R on merkkijono x kirjoitettuna takaperin. Esim. (abbc) R = cbba.

Päätösongelmat ja formaalit kielet I Yleisesti laskennallinen ongelma π on kuvaus eli funktio π : Σ Γ jossa Σ ja Γ ovat aakkostoja: syöteaakkosto Σ on se jolla kysymys, ja tulosaakkosto Γ on se jolla vastaus kirjoitetaan. Päätösongelmat ovat laskennallisten ongelmien aliluokka, jossa kunkin ongelman tapauksen vastaus on kyllä tai ei. Formaalisti päätösongelma on muotoa π : Σ B. Intuitio: Yksinkertaistetaan mutkikasta yleiskäsitettä tietokoneohjelma sellaiseksi, joka... 1. lukee syötteenä saamaansa tekstitiedostoa 2. käsittelee sitä (eräajona, siis omin päin keskustelematta käyttäjän kanssa tms.) 3. tulostaa lopuksi vastauksenaan kyllä tai ei.

Esimerkiksi päätösongelma onko annettu kymmenjärjestelmän luku alkuluku? voidaan esittää syöteaakkoston Σ = {0, 1, 2,..., 9} kuvauksena π : Σ B { 1 jos merkkijonon x esittämä luku on alkuluku, π(x) = 0 jos ei. Yleisesti, jokaista päätösongelmaa π : Σ B vastaa merkkijonojoukko A π = {x Σ π(x) = 1} eli niiden ongelman tapausten joukko, joihin vastaus on kyllä. Kääntäen, jokaista merkkijonojoukkoa A Σ vastaa päätösongelma { 1, jos x A; π A : Σ {0, 1}, π A (x) = 0, jos x / A. Tätä π A kutsutaan joukon A karakteristiseksi funktioksi koska se kertoo kuuluuko annettu x Σ joukkoon A vaiko ei.

Σ A π A 0 1 Kuva : Kielen A Σ päätös- eli tunnistusongelma π A.

Aakkoston Σ (formaali) kieli on mikä tahansa merkkijonojoukko A Σ Olemme kiinnostuneita siitä, kuuluuko annettu merkkijono annettuun merkkijonojoukkoon, eli kuuluuko annettu sana annettuun kieleen. Kielen A Σ tunnistusongelma on merkkijonojoukkoon A liittyvä päätösongelma π A : Tässä on merkkijono x Σ. Päteekö x A? Jatkossa käsittelemme vain päätösongelmia. Huomaa että tämä ei periaatteessa ole rajoitus, koska monimutkaisemmat kysymykset voi aina pilkkoa joukoksi kyllä-ei -kysymyksiä... Esimerkiksi monimutkaisempi kysymys Mikä on lukujen x ja y tulo? voidaan pilkkoa kysymyksiin Onko lukujen x ja y tulo = z vaiko ei?

Esimerkki Olkoon A aakkoston {+,, 0, 1, 2,..., 9} kieli, joka koostuu yksinkertaisista kokonaislukuvakioista (esim. Java-kielessä). Siis 0 A, +7326 A ja 32 A, mutta 2 + 3 A. Tämä kieli A on esimerkki säännöllisestä kielestä. Esimerkki Olkoon B aakkoston {+,,, (, ), 0, 1, 2,..., 9} kieli, joka koostuu laillisista kokonaislukulausekkeista. Esim. 1 + 1 B ja (1 + 2 + 3) 4 5 B, mutta (1 + 2)) B ja 3+ B. Tämä kieli B on esimerkki kontekstittomasta kielestä.

Esimerkki Muodostukoon ASCII-aakkoston kieli C niistä Java-kielisistä ohjelmista, jotka tyhjällä syötetiedostolla joutuvat ikuiseen silmukkaan. Kieli C on esimerkki ratkeamattomasta kielestä. Sitä siis ei voida tunnistaa millään tietokoneohjelmalla. Esimerkki Kieli { a k k N } on säännöllinen; kieli { a k b k k N } on kontekstiton; kieli { a k b k c k k N } on kontekstillinen (eli sen kuvaaminen vaatii kontekstitonta voimakkaamman kieliopin).

Ongelman vaikeuden arviointi päätösongelmalla Tarkastellaan mielivaltaista laskentaongelmaa π: Syötteellä x, palauta y = π(x) ja vastaavaa päätösongelmaa: Päteekö syötteellä (x, y), että y = π(x)? Tätä vastaa kielen L π = {(x, y) y = π(x)} tunnistamisen ongelma. Ongelma π voisi esim. olla neliöjuuren laskenta (vaikka alaspäin pyöristäen, eli π(x) = x ). Tiedämmekö yleisesti jotain näiden välisestä suhteesta?

Jos laskentaongelma π on ratkeava, on sitä vastaava päätösongelma myös ratkeava: Syötteellä (x, y) voidaan ensin laskea z = π(x), minkä jälkeen riittää tarkistaa onko z = y. Kääntäen: Jos päätösongelma ei ole ratkeava, myöskään vastaava laskentaongelma ei ole ratkeava.

Laskentaongelman palauttaminen päätösongelmaan Toisaalta laskentaongelman voi ratkaista soveltamalla vastaavan päätösongelman ratkaisua (M 3 ). input x M 1 M 3 Aseta Onko y = 0 π(x) = y on M 4 Tulosta ratkaisu y ei Generoi seuraava y M 2 Kuva : Laskentaongelma päätösongelmana.

Jos päätösongelma (komponentti M 3 ) on ratkeava niin ongelmakin on ratkeava helppo (jossakin mielessä) niin ongelmakin on helppo (samassa mielessä; ainakin jos testattavia ratkaisuehdokkaita y ei ole liikaa).

Kurssin ratkeavuustuloksia Erityisesti, jos kieli A kuuluu säännöllisiin kieliin, niin sen tunnistusongelma π A voidaan ratkaista helposti rakentamalla sen ratkaiseva äärellinen automaatti; kontekstittomiin niin rakentamalla pinoautomaatti; rekursiivisiin niin rakentamalla Turingin kone. Jos kieli A ei kuulu edes rekursiivisiin kieliin, niin sen π A ei ole ratkeava lainkaan. Silloin se voi olla joko osittain ratkeava eli voidaan tehdä Turingin kone joka osaa vastata kyllä mutta ei -vastauksen sijasta voi myös jäädä ikuiseen silmukkaan, tai sitten vieläkin vaikeampi jolloin se ei enää ole tietojenkäsittelyn vaan esimerkiksi matemaattisen logiikan ongelma.

Päätösongelmien ratkaisemisesta käytännössä Käytännössä päätösongelman ratkaiseminen ei useinkaan poikkea paljon vastaavan laskentaongelman ratkaisemisesta. Harvoin esim. voidaan tehdä päätöstä vaikkapa jonkin reitin olemassaolosta ilman että löydetään sellainen (mikäli on olemassa). Kurssilla käsiteltäviin tunnistusmenetelmiin liitetään käytännössä yleensä myös muuta laskentaa. Esimerkiksi tietokoneohjelman syntaksin tarkistaminen kontekstittoman kielen tunnistusongelma. Ohjelman jäsennyksen yhteydessä kuitenkin yleensä myös tuotetaan käännöksen kohdekoodi (tai siihen tarvittavat tietorakenteet).

Kielten vaikeusluokat Chomskyn kielihierarkia määrittelee seuraavat kielten vaikeusluokat: Tyyppi 3: säännölliset kielet (erikoistapauksenaan äärelliset kielet). Tyyppi 2: kontekstittomat kielet (tai yhteysvapaat tai yhteydettömät ). Tyyppi 1: kontekstilliset kielet (tai kontekstiset tai yhteyksiset ). Tyyppi 0: rajoittamattomat kielet = rekursiiviset ja rekursiivisesti lueteltavat (tai rekursiivisesti numeroituvat ) kielet. Noam Chomsky on merkittävä kielitieteilijä. Niinpä hänen hierarkiassaan on vastaava kieliopillinen näkökulma: esimerkiksi kontekstittomilla kielillä on suora yhteys tietynlaisiin formaaleihin kielioppeihin ja kontekstillisillä kielillä sellaisiin kielioppeihin, joissa huomioidaan myös lauseyhteys.

ratkeamattomat ongelmat tyyppi 0: rajoittamattomat kielet rekursiivisesti lueteltavat kielet tunnistus: universaali Turingin kone (pysähtyy "kyllä" tapauksessa) rekursiiviset kielet tunnistus: Turingin kone + riittävän mittainen työnauha (pysähtyy aina), RAM kone, ohjelmointikielet tyyppi 1: kontekstiset kielet tunnistus: Turingin kone + kohtuullisen (eli polynomisen) mittainen työnauha tyyppi 2: kontekstittomat kielet tunnistus: pinoautomaatti tyyppi 3: säännölliset kielet; tunnistus: äärellinen automaattivakiomäärä muistia äärelliset kielet Kuva : Chomskyn kielihierarkia.

Esimerkki Joillekin yksinkertaisille ohjelmointikielille (kuten Pascal) pätee Leksikaalisesti oikeiden ( muodostuu oikeista sanoista ) ohjelmien joukko voidaan esittää säännöllisillä kielillä ( oikealle lineaarinen kielioppi ). Syntaktisesti oikeiden ( sanat järkevässä järjestyksessä ) ohjelmien joukko voidaan esittää kontekstittomilla kielillä. Kontekstilliset ja rekursiiviset kielet eivät kuulu kurssin alueeseen, mutta näillä voitaisiin kuvata ohjelman suorittama laskenta... Toisaalta kaikkien ohjelmien joukkoa jotka ratkaisevat jonkin ongelman ei voi kuvata kieliopilla. Rajoittamattomat kielet koostuvat rekursiivisista kielistä, joiden tunnistusongelma on ratkeava rekursiivisesti lueteltavista kielistä, joiden tunnistusongelma on osittain ratkeava. Sellaisella kielellä on ohjelma, joka tulostaa sen merkkijonot luettelona x 0, x 1, x 2,....

Laskennallisten ongelmien ratkeavuus Läheskään kaikkia laskennallisia(kaan) ongelmia ei voida ratkaista tietokoneella yksinkertaisesti jo siksi, että ongelmia on ylinumeroituvan monta ( yhtä monta kuin reaalilukuja R ) mutta ratkaisuohjelmia vain numeroituvan monta ( yhtä monta kuin luonnollisia lukuja N ). Laskennalliset ongelmat Kaikki binäärijonot Σ={0,1} Päätösongelmat Lailliset konekieliohjelmat Ratkeavat päätösongelmat Päätösongelmien ratkaisuohjelmat

Perustelu... 1. Tietokoneohjelmat ovat merkkijonoja. 2. Minkä tahansa aakkoston merkkijonojen joukko on numeroituva. 3. Ongelman ratkaisevia tietokoneohjelmia on korkeintaan numeroituva määrä. 4. Laskennallisia ongelmia on vähintään yhtä paljon kuin päätösongelmia. 5. Minkä tahansa aakkoston päätösongelmien joukko on ylinumeroituva. 6. Laskennallisia ongelmia on ylinumeroituvan monta. 7. Jokaiselle laskennalliselle ongelmalle ei millään riitä sen ratkaisevaa tietokoneohjelmaa.

Aakkoston merkkijonoja on numeroituva määrä Lause Minkä tahansa aakkoston Σ merkkijonojen joukko Σ on numeroituva. Todistus: Olkoon Σ = {a 1, a 2,..., a n }. Kiinnitetään merkeille jokin aakkosjärjestys, esim. a 1 < a 2 < < a n. Joukon Σ merkkijonot voidaan järjestää seuraavasti (kanoniseen järjestykseen): 1. Ensin luetellaan 0:n mittaiset merkkijonot (= ε), sitten 1:n (= a 1, a 2,..., a n ), sitten 2:n (= a 1 a 1, a 1 a 2, a 1 a 3,..., a 1 a n, a 2 a 1, a 2 a 2, a 2 a 3,... ) jne. 2. Kunkin pituusryhmän sisällä merkkijonot luetellaan aakkosjärjestyksessä. Jokaiseen merkkijonoon voidaan siis liittää yksikäsitteinen luonnollinen luku, joten Σ on numeroituva.

Kuvattu luonnollisten lukujen ja merkkijonojen vastaavuus: 0 ɛ 1 a 1 2 a 2. n a n n + 1 a 1 a 1 n + 2 a 1 a 2. 2n a 1 a n 2n + 1 a 2 a 1. 3n a 2 a n. n 2 + n a na n n 2 + n + 1 a 1 a 1 a 1 n 2 + n + 2 a 1 a 1 a 2.

Päätösongelmia on ylinumeroituva määrä I Lause Minkä tahansa aakkoston Σ päätösongelmien joukko on ylinumeroituva. Todistus: Merkitään aakkoston Σ kaikkien päätösongelmien kokoelmaa Π = {π π on kuvaus Σ B}. Tehdään vastaväite: Oletetaan, että Π onkin numeroituva, eli että on olemassa numerointi Π = {π 0, π 1, π 2,...}. Olkoot Σ :n merkkijonot kanonisessa järjestyksessä lueteltuina x 0, x 1, x 2,...

Päätösongelmia on ylinumeroituva määrä II Muodostetaan uusi päätösongelma ˆπ: ˆπ : Σ B, ˆπ(x i ) = { 1, jos πi (x i ) = 0; 0, jos π i (x i ) = 1. Koska oletuksen mukaan ˆπ Π (koska Π on kaikkien päätösongelmien joukko), niin ˆπ = π k jollakin k N. Tällöin { 1, jos πk (x ˆπ(x k ) = k ) = ˆπ(x k ) = 0; 0, jos π k (x k ) = ˆπ(x k ) = 1. Tämä on ristiriita. Siis vastaoletus, että joukko Π on numeroituva, on väärä.

Todistus kuvana: Ajatellaan (ääretöntä) taulukkoa ongelmista π 0, π 1, π 2,... ja merkkijonoista x 0, x 1, x 2,.... Ongelma ˆπ poikkeaa kaikista muista ongelmista π i taulukon diagonaalilla, vaikka i kasvaisi äärettömään: ˆπ π 0 π 1 π 2 π 3 x 0 0 0 1 1 0 0 x 1 0 1 0 0 0 x 2 1 1 1 1 1 x 3 0 0 0 0........ Suomeksi: ˆπ ei voi esiintyä taulukon millään sarakkeella, joten päätösongelmia (ja yleisemmin laskennallisia ongelmia) on ylinumeroituva määrä. (Eli ˆπ eroaa jokaisesta sarakkeesta ainakin yhdessä kohtaa.) Tämä todistustekniikka on ns. Cantorin diagonaaliargumentti, jolla hän todisti, että reaalilukuja 0 x < 1 on aidosti enemmän kuin luonnollisia lukuja.

Käytännössä tämä merkitsee sitä, että kaikista laskentaongelmista voidaan esimerkiksi Java-ohjelmilla ratkaista vain häviävän pieni osa: ylinumeroituvan joukon numeroituva osajoukko. Sama pätee kaikilla ohjelmointikielillä, sillä kaikki riittävän vahvat ohjelmointikielet määrittävät täsmälleen saman ratkeavien ongelmien luokan (ns. Churchin Turingin teesi; Tämä teesi pätee jopa hypoteettisiin kvanttitietokoneisiin, vaikka ne vaikuttavatkin ratkaisevan joitakin laskentatehtäviä oleellisesti tehokkaammin kuin muut laskentamallit.). Useimmat laskennalliset ongelmat ovat siis absoluuttisesti ratkeamattomia. Valitettavasti ratkeamattomat ongelmat käsittävät myös monia mielenkiintoisia / käytännöllisiä ongelmia, erityisesti pysähtymisongelman: jos on annettu ohjelma P ja sen syöte w, niin pysähtyykö ohjelman P laskenta syötteellä w vai jääkö se ikuiseen silmukkaan? (Tämä ongelma on kuitenkin osittain ratkeava... )

Pysähtymisongelman ratkeamattomuus Näimme edellä, että valtaosa päätösongelmista on ratkeamattomia laskemalla, että niitä on paljon enemmän kuin ratkaisualgoritmeja. Osoitetaan nyt yksi konkreettinen päätösongelma ratkeamattomaksi eli että ratkeamattomuus on joidenkin oikeidenkin ongelmien piirre, eikä pelkkä matemaattinen ilmiö. Kiinnitetään laskentamalliksemme vaikkapa C-ohjelmointikieli. Church Turingin teesin nojalla sama pätee myös muillakin yhtä ilmaisuvoimaisilla laskentamalleilla. Pysähtymisongelman C-kielinen tulkinta on: Ei ole olemassa totaalista (aina pysähtyvää) C-ohjelmaa, joka ratkaisisi, pysähtyykö annettu C-ohjelma P annetulla syötteellä w.

Tehdään vastaoletus, että voitaisiinkin kirjoittaa totaalinen C-funktio bool h(char p[],char w[]) jonka syöteparametrit ovat p: merkkijono, joka sisältää tutkittavan C-kielisen ohjelman P lähdekoodin w: merkkijono, joka sisältää tutkittavan syötteen w ja jonka tulos on true jos ohjelman p suoritus syötteellä w pysähtyisi false jos se jäisi ikuiseen silmukkaan. Vastaoletusta käyttäen voitaisiin kirjoittaa toinen C-funktio void g(char p[]){ if (h(p,p)) while (true); } joka siis pysähtyy täsmälleen silloin, kun C-lähdekoodi p ei pysähtyisi saadessaan syötteenään oman itsensä.

Olkoon q tämän funktion g lähdekoodi merkkijonona. Mitä tapahtuu kutsussa g(q)? Saadaan haluttu ristiriita: Niinpä tehty vastaoletus ei pädekään. g(q) pysähtyy h(q,q) palauttaa false g(q) ei pysähdykään! Tässä todistuksessa istutetaan ns. valehtelijan paradoksi Tämä lause on valhetta! totuuden sijasta laskennan pysähtymiseen. Samaa ideaa käytti jo Kurt Gödel kuuluisissa epätäydellisyyslauseissaan istuttamalla se totuuden sijasta todistuvuuteen: Tällä väitteellä ei ole todistusta!

Säännölliset kielet ja äärelliset automaatit Äärellinen automaatti on hyvin yksinkertainen laskennan malli (eli abstrakti laskentalaite). Säännölliset kielet on se luokka laskentaongelmia, jonka näin yksinkertaisella laitteella pystyy ratkaisemaan. Näillä on sovelluksia esim. tekstihaussa ja ohjelmien syötteiden tunnistamisessa. Tavoitteet: oppia mitä ovat äärelliset automaatit ja säännölliset lausekkeet ja mikä on niiden välinen suhde muodostamaan yksinkertaisia äärellisiä automaatteja ja säännöllisiä lausekkeita tekemään muunnoksia determinististen ja epädeterminististen äärellisten automaattien ja säännöllisten lausekkeiden välillä. osoittamaan kieli joko säännölliseksi tai ei-säännölliseksi.

Esimerkki Kahviautomaatti, joka ei anna vaihtorahaa, hyväksyy vain 50 sentin ja yhden euron kolikoita ja minimimaksu on 2 euroa. Millaisia syötejonoja kahviautomaatti hyväksyy? Kelvollisia syötejonoja ovat esim. seuraavat (yksikkönä snt): 50 + 50 + 50 + 50 100 + 100 50 + 100 + 100 100 + 50 + 50 + 100 Ts. kahviautomaatti hyväksyy syötejonot, jotka ovat muotoa 50 senttiä + 50 senttiä + 50 senttiä + 50 senttiä + [0 tai useampia 50 sentin tai 1 euron kolikoita] 1 euro + 1 euro + [0 tai useampia 50 sentin tai 1 euron kolikoita] 50 senttiä + 1 euro + 1 euro + [1 tai useampia 50 sentin tai 1 euron kolikoita] 1 euro + 50 senttiä + 50 senttiä + 1 euro + [1 tai useampia 50 sentin tai 1 euron kolikoita]

Kahviautomaatin toiminta voidaan kuvata äärellisenä automaattina. Automaatin syötteitä ovat 50 sentin ja 1 euron kolikot ja automaatti hyväksyy syötejonon, jos siihen sisältyvien rahojen summa on vähintään 2 euroa Automaatti voidaan esittää tilasiirtymäkaaviona. Tämä kaavio on suunnattu verkko jonka kaaret on painotettu syöteaakkosilla. 50, 100 q 100 0 q 2 100 q 4 50 50 50 50, 100 q 1 100 q 3 Kuva : Kahviautomaatti.

Automaatilla on tiloja (5 kappaletta), jotka on esitetty ympyröinä ja nimetty q 0,... q 4, siirtymiä jotka on esitetty tilojen välisinä kaarina; aakkosto jonka symboleilla siirtymät on merkitty; alkutila (tila q 0 ) joka on merkitty tyhjästä tulevalla kaarella; ja lopputila (tila q 4 ) joka on rengastettu. Tilojen nimet ovat vapaavalintaisia, automaatin toimintaan ne eivät vaikuta.

50, 100 q 100 0 q 2 100 q 4 50 50 50 50, 100 q 1 100 q 3 Jokaiseen kahviautomaatin tilaan liittyy se tilanne, johon syötetyt lantit ovat koneen asettaneet: q 0 : Asiakas ei ole syöttänyt vielä yhtään rahaa alkutila(nne) jossa laite on, kun asiakas tulee sen luo ja alkaa syöttää siihen lanttejaan q 1 : Asiakas on syöttänyt tasan 50 senttiä rahaa. q 2 : Asiakas on syöttänyt tasan 1 euroa rahaa. q 3 : Asiakas on syöttänyt tasan 1 euro 50 senttiä rahaa. q 4 : Asiakas on syöttänyt vähintään 2 euroa rahaa joten laite voi hyväksyä saaneensa tarpeeksi rahaa, ja ryhtyä annostelemaan kahvia.

Kun annetaan tehtäväksi suunnitella automaatti hyväksymään jonkin formaalin kielen A Σ niin kannattaa miettiä 1. ensiksi mitä tilanteita automaatin pitää muistaa, jotta se voisi tehdä oikean päätöksen siitä, kuuluuko sen nykyinen syöte x Σ kieleen A vaiko ei. Näin saadaan automaattiin tarvittavat tilat. Kahviautomaatissa muistetaan tähän mennessä syötetty rahasumma. 2. toiseksi miten näiden tilanteiden välillä siirrytään, kun syötettä x luetaan merkki merkiltä. Näin saadaan automaattiin tarvittavat siirtymät. Kahviautomaatissa jokainen lantti on oma merkkinsä, ja se vie nykyisestä rahasummasta seuraavaan.

Äärellisen automaatin esitystapoja Tilasiirtymäkaaviona eli piirroksena. q Tila q q 0 Alkutila Lopputila eli hyväksyvä tila a q q Tilasiirtymä δ(q, a) = q Kuva : Tilasiirtymäkaavion merkinnät.

Tilasiirtymätaulukkona jossa jokaisella tilalla on oma rivinsä jokaisella syöteaakkosella on oma sarakkeensa tilan p sarake c ilmoittaa tilan (eli rivin) jonne siirrytään tilasta p merkillä c. 50 snt 1 euro q 0 q 1 q 2 q 1 q 2 q 3 q 2 q 3 q 4 q 3 q 4 q 4 q 4 q 4 q 4 q 0 100 q 2 50 50 50 q 1 100 q 3 50, 100 100 q 4 50, 100

Esimerkki Etumerkillisen kokonaisluvun tunnistaminen. Tilasiirtymäkaaviona (jossa d = {0, 1,..., 9} ovat 10-järjestelmän lukumerkit): d +, d q 0 q 1 q 2 d Tilasiirtymätaulukkona: d +, q 0 q 2 q 1 q 1 q 2 q 2 q 2 Taulukon puuttuvat kohdat vastaavat virhetilaa Error.

Tehtävä C-kielessä 0-alkuiset luvut tulkitaan oktaaliluvuiksi (jolloin merkkejä 8 ja 9 ei sallita lainkaan), ja 1... 9-alkuiset 10-kantaisiksi luvuiksi. Muuta esimerkin automaattia siten, että nämä tapaukset erotellaan, eli että ne johtavat eri hyväksyviin tiloihin. Tehtävä C-kielessä 0x-alkuiset luvut tulkitaan heksadesimaaliluvuiksi. Ota tämäkin huomioon.

Ohjelmana (esim. C:llä): int q=0; int c; while ((c=fgetc(stdin))!= EOF) switch (q) { case 0: if (c== + c== - ) q=1; else if (isdigit(c)) q=2; else q=3; break; case 1: if (isdigit(c)) q=2; else q=3; break; case 2: if (isdigit(c)) q=2; else q=3; break; case 3: break; } d q 0 +, q 1 d q 2 d

Esimerkki C-kielen etumerkittömän liukulukuvakion tunnistus: 1. d 2 3 d. d e,e 4 d e,e 5 +, 6 d d 7 d d. E, e +, 1 3 2 2 4 3 3 4 5 4 4 5 5 7 6 6 7 7 7

Äärellisen automaatin formaali määrittely Äärellinen automaatti M koostuu seuraavista osista: ohjausyksiköstä jossa on äärellinen määrä tiloja ja jonka toimintaa ohjaa automaatin siirtymäfunktio δ syötenauhasta joka on jaettu yhden syötemerkin kokoisiin paikkoihin. nauhapäästä joka kullakin hetkellä osoittaa yhtä syötenauhan merkkipaikkaa. i n p u t q1 q2 q0 δ

Automaatin toiminta Automaatti käynnistetään erityisessä alkutilassa q 0, siten että tarkasteltava syöte on kirjoitettuna syötenauhalle ja nauhapää osoittaa sen ensimmäistä merkkiä. Yhdessä toiminta-askelessa automaatti lukee nauhapään kohdalla olevan syötemerkin, päättää ohjausyksikön tilan ja luetun merkin perusteella siirtymäfunktion mukaisesti ohjausyksikön uudesta tilasta, ja siirtää nauhapäätä yhden merkin eteenpäin. Automaatti pysähtyy, kun viimeinen syötemerkki on käsitelty. Jos ohjausyksikön tila tällöin kuuluu erityiseen (hyväksyvien) lopputilojen joukkoon, niin automaatti hyväksyy syötteen, muuten hylkää sen. Automaatin tunnistama kieli on sen hyväksymien merkkijonojen joukko.

Määritelmä Äärellinen automaatti on viisikko M = (Q, Σ, δ, q 0, F ), missä Q on automaatin tilojen äärellinen joukko; Σ on automaatin syöteaakkosto; δ : Q Σ Q on automaatin siirtymäfunktio; q 0 Q on automaatin alkutila; F Q on automaatin hyväksyvien tilojen joukko. Siirtymäfunktio δ on määritelmän kiinnostavin osa. Intuitiivisesti: Jos automaatti on nyt tilassa q ja seuraavaksi tulee merkki c niin silloin siirrytään tilaan δ(q, c), eli siihen jonka siirtymäfunktio ilmoittaa. Toisin sanoen: Siirtymäfunktion arvo δ(q, c) = tilasiirtymätaulukon sisältö sen rivillä q ja sarakkeella c.

Esimerkki Kokonaislukuautomaatin formaali esitys on d +, d q 0 q 1 q 2 d d +, q 0 q 2 q 1 q 1 q 2 q 2 q 2 M = ({q 0, q 1, q 2, error}, {0, 1,..., 9, +, }, δ, q 0, {q 2 }), jossa δ on kuten taulukossa; esim. jne. δ(q 0, 0) = δ(q 0, 1) = δ(q 0, 2) = = δ(q 0, 9) = q 2 δ(q 0, +) = δ(q 0, ) = q 1 δ(q 1, +) = δ(q 1, ) = error

Automaatin laskennan matemaattinen esitys Automaatin tilanne on pari (q, w) Q Σ jossa q = automaatin nykyinen tila w = syötemerkkijonon vielä käsittelemätön loppuosa. Erityisesti automaatin alkutilanne syötteellä x on pari (q 0, x) jossa q 0 on automaatin alkutila. Tilanne (q, cw), jossa c Σ on seuraava syötemerkki, johtaa suoraan tilanteeseen (δ(q, c), w). Tätä merkitään lyhyesti (q, cw) (δ(q, c), w). Tilanne (q, w) johtaa tilanteeseen (q, w ) jos on olemassa tilannejono (q 0, w 0 ) (q 1, w 1 ) (q 2, w 2 ) (q 3, w 3 ) (q n, w n ) missä (q 0, w 0 ) = (q, w) ja (q n, w n ) = (q, w ) (jollakin n N). Tätä merkitään lyhyesti (q, w) (q, w ).

Jos halutaan merkitä näkyviin minkä automaatin M tilannejonoista on kyse, niin voidaan käyttää alaindeksiä: siis M ja M. Automaatti M hyväksyy syötemerkkijonon x Σ, jos ja muuten hylkää sen. (q 0, x) (q f, ε) jollain q f F Toisin sanoen, automaatti M hyväksyy syötteen x, jos sen vastaava alkutilanne (q 0, x) johtaa johonkin hyväksyvään lopputilanteeseen, jossa koko syöte on luettu. Vastaavaa tilannejonoa (q 0, x) M (q, ε) kutsutaan automaatin M laskennaksi syötteellä x. Se on siis hyväksyvä laskenta jos lopputila q F ja hylkäävä jos q F.

Vaihtoehtoisesti voidaan laajentaa siirtymäfunktion δ yksittäisiltä merkeiltä a Σ kokonaisille merkkijonoille w Σ (ja niin teemmekin jatkossa): δ (q, w) = q silloin kun (q, w) (q, ε). (1) Siis δ (q, w) on se tila, johon päästään aloittamalla tilasta q ja lukemalla merkkijono w loppuun saakka. Erityisesti δ (q, ε) = q ja δ (q, a) = δ(q, a), kun a Σ. Automaatti siis hyväksyy merkkijonon w, jos δ (q 0, w) F.

Tämä on helppo määritellä myös rekursiivisesti: { δ q jos w = ε (q, w) = δ (δ(q, a), v) jos w = av jossa a Σ Tästä saadaan suoraan rekursiivinen algoritmi, jonka rekursio on niin yksinkertaista (ns. häntärekursiota), että se on helppo toteuttaa while-silmukkana.

Säännöllinen kieli Automaatti M tunnistaa kielen { } L(M) = x Σ (q 0, x) (q f, ε) jollakin q f F M = {x Σ δ (q 0, x) F } eli niiden merkkijonojen x joukon, jotka M hyväksyy. Sanomme, että kieli A on säännöllinen, jos jokin äärellinen automaatti tunnistaa sen, ts. A = L(M) jollain M. Huomaa, että säännöllisyys on kielen, eli merkkijonojoukon ominaisuus, ei yksittäisen merkkijonon. Ei ole mielekästä kysyä yksittäisestä merkkijonosta, onko se säännöllinen. (Mistä tahansa merkkijonosta w Σ voidaan toki muodostaa yksialkioinen kieli {w} Σ, joka on selvästi säännöllinen.)

Esimerkki Merkkijonon +1210 hyväksyminen kokonaislukuautomaatilla: d +, d q 0 q 1 q 2 d (q 0, +1210) (q 1, 1210) (q 2, 210) (q 2, 10) (q 2, 0) (q 2, ε) Nyt jäätiin hyväksyvään lopputilaan q 2 eli +1210 L(M). Laittoman merkkijonon 12 + 10 laskenta onkin hylkäävä: (q 0, 12 + 10) (q 2, 2 + 10) (q 2, + 10) (error, 10)

Äärelliseen automaattiin voidaan helposti lisätä muutakin tulostusta ja toimintoja kuin pelkkä hyväksyminen tai hylkääminen. Nämä ovat pelkkiä sivuvaikutuksia eivätkä ne vaikuta automaatin toimintaan siihen, miten se valitsee tilasiirtymänsä...... tai jos ne vaikuttavat, niin silloin kyseessä ei enää olekaan äärellinen automaatti, vaan jokin muu sitä vahvempi laskennan malli. Tällaiset modifikaatiot eivät tämän kurssin kannalta tuo mitään kovin oleellista uutta asiaan. Muissa yhteyksissä ne voivat kuitenkin olla hyvinkin hyödyllisiä.

Esimerkki Lisätään etumerkillisen kokonaisluvun tunnistamiseen toiminto, joka laskee luvun arvon muuttujaan value eli muuntaa syötemerkkijonon sitä vastaavaksi kokonaisluvuksi. d q 0 +, q 1 d q 2 d int q=0; int c; int sign=1; int value=0; while ((c=fgetc(stdin))!= EOF) switch (q) { case 0: if (c== + ) q=1; else if (c== - ) { q=1; sign=-1; } else if (isdigit(c)) { q=2; value=c- 0 ; } else q=3; break; case 1: if (isdigit(c)) { q=2; value=sign*(c- 0 ); } else q=3; break; case 2: if (isdigit(c)) { q=2; value=10*value+sign*(c- 0 ); } else q=3; break; case 3: break; }

Sivuhuomautus: Äärellisen automaatin tämän tapainen formaalimpi laajennus on nimeltään äärellinen transduktori (finite state transducer). Tässä jokaiseen tilaan liittyy paitsi yhden syötemerkin lukeminen, niin myös yhden (tai useamman) tulostemerkin kirjoittaminen erilliselle tulostenauhalle (tai syötteen päälle). Ohjelmointikielten kääntämisessä ensimmäinen vaihe on leksikaalinen analyysi eli selaus. Tarkoituksena on poimia ja erotella ohjelman lähdekoodista erityyppiset alkiot, kuten kokonaislukuvakiot (arvoineen), varatut sanat (if, else, while, jne.), muuttujien nimet, jne. Siis esimerkiksi nähtyään merkit for tällainen selain lukee vielä yhden merkin c eteenpäin. Jos tämä c on jokin muuttujan nimessä sallittu merkki, niin se tietää kokoavansa nyt muuttujan nimeä muotoa forc... ; muuten se tietääkin löytäneensä varatun sanan for ja tämä c kuuluukin seuraavaan alkioon.

Selain voidaan toteuttaa (ja usein toteutetaan) yhtenä äärellisenä transduktorina, joka lukee lähdekooditiedostoa merkki merkiltä ja nähtyään jonkin kokonaisen alkion tulostaa vastaavan tiedon. Selainta ei kuitenkaan (yleensä) koodata käsin, vaan sen koodi voidaan tuottaa automaattisesti ohjelmointikielen kuvauksesta jollain sopivalla työkalulla (esim. lex ja sen GNU-versio flex), joka myös voi automaattisesti liittää hyväksyviin tiloihin käyttäjän määrittelemän toimintokoodin (tulostuksen yms.).

fredriks@cs ~$ cat ex.lex %{ #include <stdio.h> %} %option noyywrap %% [0-9]+ { printf("kokonaisluku: %s\n",yytext); } lap { printf("lap!\n"); } /* Tunnistetaan "lap" */. { } /* Sivuutetaan muu */ %% int main(void) { yylex(); return 0; } fredriks@cs ~$ flex ex.lex fredriks@cs ~$ gcc lex.yy.c -o foo fredriks@cs ~$./foo abc123def456lapxxxxx Kokonaisluku: 123 Kokonaisluku: 456 LAP!

Tehtävä Tee paranneltu versio kahviautomaatista: automaatti hyväksyy vain tasarahan, mutta lisäksi siihen on lisätty sellainen peruutusnappi, joka palauttaa kaikki syötetyt kolikot (antamatta kahvia). Tehtävä Laadi aakkoston Σ = {a, b} äärellinen automaatti joka tunnistaa kielen {w w sisältää täsmälleen kaksi a:ta}. Tehtävä Edellisen komplementti: laadi äärellinen automaatti joka tunnistaa kielen {w w ei sisällä täsmälleen kahta a:ta}. Tehtävä Laadi automaatti kielelle: {w w ei muodostu pelkästä a:sta tai b:stä}

Tehtävä Laadi automaatti kielelle: {w w ei sisällä jonoa aab} Tehtävä Osoita että kieli {(aba) n n > 0} on säännöllinen. Tehtävä Tarkastellaan kieltä, joka koostuu niistä merkkijonoista, joissa jokainen pariton (eli ensimmäinen, kolmas, viides,... ) merkki on a. Osoita, että se on säännöllinen. Tehtävä Laadi äärellinen automaatti, joka tunnistaa kielen L = {0 n 1 m n, m N} {1 n 0 m n, m N}.

Äärellisen automaatin laskentavoimasta Kieli L 1 = {0 n 1 m n, m N} on helppo tunnistaa äärellisellä automaatilla, eli se on säännöllinen. Äärellinen automaatti on hyvin rajoittunut laskennan malli. Vaikkapa niinkin yksinkertainen kieli kuin L 2 = {0 n 1 n n N} (eli merkkijonot joissa on ensin jono nollia ja sitten saman verran ykkösiä) ei olekaan säännöllinen! (Tähän palataan.) Mikä on se perustava ero näiden kielten välillä, joka tekee toisesta helpon ja toisesta mahdottoman tunnistaa äärellisellä automaatilla?

Intuitiivisesti, kielen L 1 = {0 n 1 m n, m N} tunnistaminen vaatii vain vakiomäärän muistia. Kieli L1 = merkkijonot jossa on ensin pelkkiä nollia ja sitten pelkkiä ykkösiä. Siis niiden lukumäärällä ei ole väliä, ja riittää muistaa mikä oli edellinen merkki (tila). Toisaalta, kielen L 2 = {0 n 1 n n N} tunnistamiseen ei riitäkään vakiomäärä muistia. L 2 = merkkijonot jossa on ensin jokin määrä n nollia ja sitten yhtä monta ykköstä. Tässä tämä yhteinen n voi olla kuinka suuri tahansa sehän riippuu syötteen pituudesta. Äärellinen automaatti -parka ehtii unohtaa montako nollaa se on nähnyt ennen kuin ykköset alkavat, kun n on riittävän suuri. Formalisoimme tämän myöhemmin niin sanottuna pumppauslemmana.

Toisaalta ominaisuutta vakiomäärä muistia käyttävät kaikki automaattimme, esim. kahviautomaattimme 50, 100 q 100 0 q 2 100 q 4 50 50 50 50, 100 q 1 100 q 3 muistaa syötetyn kokonaisrahasumman, jos se on < 200 senttiä. Muuten se muistaa vain että syötetty summa on 200 senttiä. Eli se muistaa vain äärellisen monta eri vaihtoehtoa.

Esimerkki Tunnistetaan binäärijonot, joiden toiseksi viimeinen merkki on nolla: 0?? 1 0?0 0 00 0 10 0?1 0 1 1 0 1 1 01 1 11 Automaatti muistaa kaksi viimeistä lukemaansa bittiä. Tilat on nimetty näiden mukaan: tilassa 01 viimeisin luettu bitti oli 1 ja edeltävä oli 0. 1

Aakkostot Aakkosto Σ voidaan määritellä varsin vapaasti ja sovellukseen sopivaksi. Esim. Γ = {omena,päärynä,appelsiini} tai Σ = {[ 0 0 0 ], [ 0 0 1 ], [ 0 1 0 ], [ 0 1 1 ],..., [ 1 1 1 ]}. Aakkoston Σ muodostavat siis kolmebittiset binäärivektorit; Σ = 2 3 = 8. Aakkoston Σ syötteitä voidaan kutsua kolmiuraisiksi. Esimerkiksi 4-merkkisessä syötteessä [ 0 0 0 ] [ 1 0 0 ] [ 0 0 1 ] [ 0 1 0 ] voidaan mieltää kolme rinnakkaista uraa: ylin, keskimmäinen ja alin.

Automaatti lukee näitä uria samaan tahtiin rinnakkain, sillähän on vain yksi lukupää. Tehtävä Jono aakkoston Σ symboleja määrittelee kolme riviä ykkösiä ja nollia. Tulkitaan nämä binäärilukuina, joissa eniten merkitsevä bitti on oikealla. Olkoon L = {w Σ alin rivi on kahden ylemmän rivin summa} Esimerkiksi [ 1 1 0 eli ] [ 1 0 0 ] [ 0 0 1 ] L mutta [ 1 0 1 ] [ 0 0 1 ] L Osoita että tämä kieli L on säännöllinen. 3 + 1 = 4 mutta 1 + 0 3.

Ratkaisu: Todistetaan kieli (määritelmän mukaan) säännölliseksi osoittamalla, että sillä on sen tunnistava äärellinen automaatti: A D {[ 0 ] [ 1 ] [ 0 ]} {[ 1 ]} B A = 0, 0, 1 B = 1 0 1 1 0 0 1 C D = {[ 1 0 0 ], [ 0 1 0 ], [ 1 1 1 ]} C = {[ 0 0 1 ]} Tilan nimi = muistibitin arvo. Siirtymä suoritetaan, kun muistibitin + ylimmän uran bitin + keskiuran bitin summassa vähemmän merkitsevä bitti = alimman uran bitti, ja enemmän merkitsevä bitti = seuraava muistibitti eli kohdetila.

Tehtävä Olkoon Σ = {[ 0 0 ], [ 0 1 ], [ 1 0 ], [ 1 1 Jono aakkoston Σ symboleja määrittelee kaksi uraa ykkösiä ja nollia. Tulkitaan nämä binäärilukuina, joissa eniten merkitsevä bitti on oikealla. Olkoon ]}. L = {w Σ alin rivi on kolme kertaa ylin rivi} Esimerkiksi [ 1 1 ] [ 0 1 ] [ 1 1 ] [ 1 0 ] [ 0 0 ] [ 0 1 ] L ja [ 1 1 ] [ 0 1 ] L eli Osoita että tämä kieli L on säännöllinen. 13 3 = 39 ja 1 3 = 3.

Ratkaisu: Samaan tapaan kuin edellinen tehtävä, mutta nyt muistibittejä voi olla kaksi: 0 0 1 1 0 1 10 1 0 1 1 0 1 0 0 0 3 = 0, 1 3 = 3 = (11) 2, eli tulokseen tulee 1 ja muistiin laitetaan 1. Jos muistissa on 1, ja lasketaan 0 3, tulokseksi tulee 1 (muistista), jos taas 1 3, tulos on 4 = (100) 2, joten tulosbitti on 0 ja muistiin jää 10, jne...

Tämän (ja edellisen) tehtävän ratkaisu tunnistaa kuuluuko syöte kieleen. Jos haluaisi oikeasti tehdä yhteenlaskukoneen (tai syötteen vakiolla kertovan koneen), niin ratkaisu voidaan helposti muuttaa transduktoriksi, jonka syötteenä luettaisiin vain ylintä (ja keskimmäistä) uraa, ja tulosteena kirjoitettaisiin alinta uraa. (Kahden syöteluvun kertolaskua ei kuitenkaan voine toteuttaa äärellisenä automaattina.) Jos ei käytettäisikään ura-aakkostoa, vaan aakkostona olisikin Σ = {0, 1, +, =}, niin kieli L = {x + y = z x, y ja z ovat binäärilukuja ja luku z on lukujen x ja y summa} ei olekaan säännöllinen: jos x ja y ovat tarpeeksi suuria lukuja, niin äärellinen automaatti ehtii unohtaa ne lukiessaan syötettä.

Sovelluksista Äärelliset automaatit sellaisenaan ovat hyödyllisiä merkkijonojen käsittelyssä, mistä myöhemmin lisää... Lisäämällä tilasiirtymiin satunnaisuutta saadaan Markovin ketjut eli satunnaisprosessit, joilla on äärellinen muisti. Perusversiossa Markovin ketjuihin ei tosin liity mitään syötettä. Markovin piilomallit (hidden Markov models) ovat lähempänä tässä esitettyjä äärellisiä automaatteja. Tilasiirtymäjärjestelmiä käytetään (etenkin hajautettujen järjestelmien) spesifioinnissa ja verifioinnissa.

Sovellus: viestinvälitysprotokollat Erilaisia protokollia voidaan kuvata äärellisinä automaatteina tai tilakoneina. Tarkastellaan yksikertaista vuorottelevan bitin protokollaa, jossa lähettäjäprosessi S ja vastaanottajaprosessi R kommunikoivat. S lähettää paketteja d 0, d 1, d 2,.... Paketti voi hukkua matkalla (kuten kuvassa d 1 ). R kuittaa saadun paketin (viestillään a) ja S lähettää seuraavan paketin lähetetään vasta kun on saanut edellisestä kuittauksen. Jos kuittausta ei kuulu sovitussa ajassa, niin paketti lähetään uudestaan: S timeout d 0 d 1 d 1 d 2 R a a a

Ongelma: Jos kuittaus a hukkuu, niin R voi saada duplikaattiviestin: S timeout d 0 d 1 d 1 d 2 R a a a a

Ongelma: Jos kuittaus a hukkuu, niin R voi saada duplikaattiviestin: S timeout d 0 d 1 d 1 d 2 R a a a a Ratkaisu 1: Numeroidaan viestit ja kuittaukset: timeout S d 0, 0 d 1, 1 d 1, 1 d 2, 2 R a, 0 a, 1 a, 1 a, 2

Ongelma: Jos kuittaus a hukkuu, niin R voi saada duplikaattiviestin: S timeout d 0 d 1 d 1 d 2 R a a a a Ratkaisu 1: Numeroidaan viestit ja kuittaukset: timeout S d 0, 0 d 1, 1 d 1, 1 d 2, 2 R a, 0 a, 1 a, 1 a, 2 Mutta tällöin tarvittaisiin yhä suurempia ja suurempia numeroita 0, 1, 2...

Protokollan parannus Riittää käyttää kahta numeroa (0 ja 1 parillinen/pariton viesti ): S timeout d 0, 0 d 1, 1 d 1, 1 d 2, 0 R a, 0 a, 1 a, 1 a, 0 S ja R voidaan mallintaa tilasiirtymäjärjestelminä:

Vuorottelevan bitin protokolla tilakoneina lähettäjä S a, 1 vastaanottaja R a, 1 d, 1 timeout timeout d, 0 d, 1 d, 1 d, 0 d, 1 d, 0 a, 0 d, 0 a, 0 Jos S ei saa ajoissa symbolia a, niin se lukee sen sijaan timeout-symbolin.

Epädeterministiset äärelliset automaatit Epädeterminismi tarkoittaa, ettei koskaan tarvitse myöntää olevansa väärässä. Anon. Epädeterministisellä automaatilla siirtymäfunktio δ liittää nykyisen tilan ja syötemerkin pariin (q, x) äärellisen joukon vaihtoehtoisia seuraavia tiloja. Epädeterministinen automaatti hyväksyy merkkijonon x jos sille on olemassa jokin hyväksyvä laskenta. Siis se hylkää merkkijonon x vain jos kaikki sen laskennat ovat hylkääviä. Ihan loogisesti: koska niin kääntäen x hyväksytään sille on jokin hyväksyvä laskenta x hylätään ei niin, että sille olisi jokin hyväksyvä laskenta sen kaikki laskennat hylkäävät.

Esimerkiksi epädeterministinen automaatti a a a b a q 0 q 1 q 2 q 3 b b hyväksyy syötemerkkijonon abbaba, koska sillä on hyväksyvä laskenta (q 0, abbaba) (q 0, bbaba) (q 0, baba) (q 0, aba) (q 1, ba) (q 2, a) (q 3, ε). Sillä on myös hylkääviä laskentoja kuten (q 0, abbaba) (q 0, bbaba) (q 0, baba) (q 0, aba) (q 0, ba) (q 0, a) (q 0, ε) mutta niitä ei siis oteta huomioon.

Determinismi vs. epädeterminismi Deterministisessä automaatissa siirtymä tarkoittaa, että nykyisestä tilasta mennään aina kohdetilaan sen δ(q, a). Epädeterministisessä automaatissa siirtymä r δ(q, a) tarkoittaakin, että tilasta q syötemerkillä a on mahdollista mennä tilaan r. Mutta voi olla muitakin mahdollisuuksia s δ(q, a). Deterministinen automaatti hyväksyy, jos se ainoa mahdollinen lopputilanne on hyväksyvä. Epädeterministinen automaatti hyväksyy, jos on mahdollista päätyä hyväksyvään lopputilanteeseen. Eli jos on jokin tapa valita aina sopivasti nykyiselle tilalle q i seuraava tila q i+1 δ(q i, a i ) siten, että syötteen a 0 a 1 a 2... a n loputtua ollaan jossakin hyväksyvässä tilassa q n. Tämä näyttää epäilyttävän epämekaaniselta: miten nykyisessä tilassa q i voitaisiin osata tehdä juuri oikea valinta näkemättä syötteen loppuosaa a i+1 a i+2 a i+3... a n? Epädeterminismillä onkin erilaisia tulkintoja, kuten:

Spesifikaationa, jossa kuvaillaan minkälaiset merkkijonot pitäisi hyväksyä, kertomatta tarkasti miten niiden hyväksyntä etenisi askel askeleelta. Etsintänä, jossa on operaatio etsi reitti tästä tilanteesta johonkin hyväksyvään lopputilanteeseen. Tämä voitaisiin mekanisoida vaikkapa TRA-kurssin keinoin syvyyssuuntaisena etsintänä kaikkien tilanteiden verkosta: DFS(q, x) : 1 if merkkijono x = ε 2 then return onko tila q hyväksyvä vaiko hylkäävä 3 else olkoon x = ay jossa a Σ ja y Σ 4 for each r δ(q, a) 5 do if DFS(r, y) 6 then return true 7 return false Epädeterministinen automaatti M = (..., q 0, F ) hyväksyy syötteen w jos kutsu DFS(q 0, w) palauttaa arvon true.

Rinnakkaisuutena, jossa epädeterministinen automaatti seuraa mahdollisia laskentojaan rinnakkain: Deterministinen Epädeterministinen laskenta laskenta...... hyväksy tai hylkää hyväksy hylkää Epädeterministiset laskennat muodostavat siis kokonaisen laskentapuun, jonka haarat vastaavat eri valintakohtia.

Ilmaisena neuvona. Epädeterministisen automaatin voidaan ajatella saavan jokaisessa valintatilanteessaan Mihinköhän seuraavista mahdollisista tiloista δ(q, a) minun kannattaisi siirtyä? jostakin ulkopuolelta vastauksen Siirry tilaan r, luota minuun! Silloin automaatin itsensä tehtäväksi jää vain varmentaa että sen saamat neuvot olivat oikein. Tai jos ajatellaan etsintää, niin automaatti ei itse joudu tekemään raskasta työtä, vaan työn tekee neuvonantaja ja automaatti saa työn tulokset ilmaiseksi. Tämän tulkinta tulee erityisen kiinnostavaksi silloin kun tarkastellaan automaatteja vahvempia laskentamalleja mutta rajoitetaan niille annettavien resurssien määrää esimerkiksi P? = NP-ongelma saa silloin tulkinnan jos jokin vastaus voidaan varmentaa nopeasti, niin voisiko sen myös laskea nopeasti ilman neuvojakin?.

Tärkeä tulos Deterministiset (Deterministic Finite Automata, DFA) ja epädeterministiset (Nondeterministic Finite Automata, NFA) automaatit tunnistavat täsmälleen samat kielet (eli säännölliset kielet). DFA ja NFA ovat ilmaisuvoimaltaan yhtä vahvoja laskennan malleja niillä voidaan hyväksyä samat kielet. Epädeterminismiä käyttämällä kielen esitystä voidaan kuitenkin usein selkeyttää ja yksinkertaistaa.

Epädeterministisessä automaatissa sallitaan myös ε-siirtymiä kuten kuvassa. Tällaisen ε-siirtymän kuten 1 ε 2 tulkinta on, että sitä pitkin pääsee tilasta 1 tilaan 2 lukematta yhtään syötemerkkiä. a a a 0 b 1 2 3 b ε b Kuva : Epädeterministinen automaatti jossa on siirtymä tyhjällä merkkijonolla.

a a a a 0 0 b 1 2 3 b 0 b ε b b 0 1 2 Esimerkkinä syöte abbab Automaatti hyväksyy syötteen, koska sillä on kaksikin hyväksyvää laskentaa. a b 0 1 2 3 0 2 2 0 1 2 3 3

Seuraava NFA hyväksyy aakkoston {a, b, c} merkkijonot, joissa on osajonona ensin abb ja sen jälkeen ca tai ac. Huomaa ε-siirtymien mahdollistama modulaarisuus. a,b,c a,b,c ε "abb moduuli" a b b "mitä tahansa moduuli" ε ε "ca moduuli" c a ε a,b,c ε a c ε "ac moduuli"

Määritelmä Epädeterministinen äärellinen automaatti on viisikko M = (Q, Σ, δ, q 0, F ) jossa Q on äärellinen tilojen joukko, Σ on äärellinen syöteaakkosto, δ : Q Σ P(Q) on joukkoarvoinen siirtymäfunktio siis sen arvot δ(q, a) Q ovat tilajoukon Q osajoukkoja q 0 Q on alkutila ja F Q hyväksyvien lopputilojen joukko. Muista: Matematiikassa merkintä P(S) tarkoittaa joukon S potenssijoukkoa {X X S} eli kaikkien niiden joukkojen X joukkoa, jotka voidaan muodostaa joukon S alkioista. Esimerkiksi P({,, }) = {, { }, { }, { }, {, }, {, }, {, }, {,, }}.

Esimerkki a a q 0 a q 1 b q 2 a q 3 b b a b q 0 {q 0, q 1 } {q 0 } q 1 {q 2 } q 2 {q 3 } q 3 {q 3 } {q 3 } Nyt virhetilanne on helposti ilmaistavissa tyhjän seuraajatilajoukon avulla. Siirtymätaulukossa voidaan jättää joukkosulut poiskin: siis joukkoa {q 0, q 1 } voidaan merkitä myös suoraan sen alkioiden listana q 0, q 1. Tilanne (q, w) voi johtaa suoraan tilanteeseen (q, w ), jota merkitään samoin kuin ennen eli (q, w) (q, w ), jos w = aw ja q δ(q, a). Silloin (q, w ) on M tilanteen (q, w) mahdollinen välitön seuraaja. Muutoin määritelmät epädeterministisille automaateille ovat samat kuin aiemmin.

Tärkeän tuloksemme DFA NFA perustelua : Selvästikin deterministiset automaatit ovat epädeterminististen erikoistapaus jossa aina δ(q, a) 1. Siten kaikki edellisillä tunnistettavat kielet ovat tunnistettavissa myös jälkimmäisillä. : Mutta myös kääntäen (ja tämä on se yllättävämpi ja vaikeampi suunta): Jokaiselle epädeterministiselle automaatille M on olemassa saman kielen tunnistava deterministinen automaatti M. Tämä osoitetaan myöhemmin kehittämällä menetelmä, jolla syötteenä saadusta automaatista M voidaan muodostaa sitä vastaava M eli menetelmä determinisoida M.

Tehtävä Laadi sellainen aakkoston Σ = {a, b} epädeterministinen automaatti, joka hyväksyy täsmälleen ne merkkijonot, joissa esiintyy sekä merkkijono abba että merkkijono baba. Huomaa, että nämä esiintymät saavat olla päällekkäinkin: siis esimerkiksi merkkijono aaaabbababbb hyväksytään, koska siinä on alle- ja ylleviivauksella merkityt esiintymät. Tehtävä Laadi deterministinen automaatti edellisen tehtävän kielelle.

Epädeterministisen automaatin simulointi Palataan aiempaan esimerkkiin: a a a 0 b 1 2 3 b ε b Kirjoitetaan algoritmi, joka ylläpitää muuttujassa NykyisetTilat listaa niistä tiloista, joissa automaatti voi olla.

0 Algoritmi käy laskentapuuta läpi leveyssuuntaisesti. NykyisetTilat = laskentapuun taso Kullakin askeleella sitä päivitetään laskemalla 1. saatua syötemerkkiä vastaavat seuraajatilat ja 2. ne tilat, joihin niistä päästään ε-siirtymillä. a b b a b 0 0 1 2 0 1 2 3 0 2 2 0 1 2 3 3

Tilajoukon R Q ε-sulkeuma E(R) koostuu niistä tiloista, joihin tilajoukosta R pääsee ε-kaaria pitkin. Siis R E(R) koska jokaisesta tilasta pääsee suoraan itseensä ilman yhtään (edes ε-)siirtymää, ja jos tilasta s E(R) on ε-siirtymä s ε t niin myös sen kohdetila t E(R). SimulateNFA(M, syöte): 1 NykyisetTilat E(q 0 ) // alkutilan ε-sulkeuma 2 while syötettä on yhä jäljellä 3 do a lue seuraava syötemerkki 4 SeuraajaTilat 5 for q NykyisetTilat 6 do SeuraajaTilat SeuraajaTilat δ M (q, a) 7 SeuraajaTilat E(SeuraajaTilat) 8 NykyisetTilat SeuraajaTilat 9 return F NykyisetTilat // onko saavutettu joku lopputila?

Algoritmi SimulateNFA tulkkaa epädeterministisen laskennan deterministiseksi. Yksittäinen syötemerkki käsitellään (pahimmassa tapauksessa) ajassa O( Q 2 ). Tästä tulkkauksesta päästään eroon kääntämällä, eli muodostamalla deterministinen automaatti, joka tunnistaa saman kielen. Menetelmä muodostaa DFA:n siirtymätaulukon siis etukäteen. Muuttujan NykyisetTilat arvot kuuluvat potenssijoukkoon P(Q). Siten sillä on korkeintaan P(Q) = 2 Q mahdollista arvoa joten voimme muodostaa äärellisen DFA:n laittamalla kukin mahdollinen NykyisetTilat-arvo omaksi tilakseen ja siirtymät kuten SimulateNFA ne laskisi.

Siis muodostamme NFA:sta M DFA:n M seuraavasti: Aakkosto on molemmilla sama Σ. Tilajoukko Q bm = P(Q M ). Siirtymäfunktio koostuu siirtymistä NykyisetTilat a SeuraajaTilat jossa nämä muuttujat NykyisetTilat, a ja SeuraajaTilat ovat kuten tulkkialgoritmin SimulateNFA riveillä 4 7. Eli kun annetaan tila NykyisetTilat Q bm ( P(Q M )), niin käydään läpi jokainen a Σ, ja lasketaan sille vastaava SeuraajaTilat P(Q M ) ( Q bm ). Alkutila on kuten sen rivillä 1: E(q 0 ), missä q 0 on NFA:n M alkutila. Hyväksyvät tilat ovat kuten sen rivillä 9: ne tilat, joihin sisältyy ainakin yksi NFA:n M lopputila.

1 Alusta tulos M sisältämään alkutila nimeltä E(NFA:n M alkutila q 0 ) ilman yhtään kaarta, ja merkitse se uudeksi 2 while tuloksessa M on uusia tiloja 3 do NykyisetTilat ota jokin niistä ja merkitse se vanhaksi 4 if joukkoon NykyisetTilat kuuluu ainakin yksi epädeterministisen automaatin M hyväksyvä tila 5 then merkitse NykyisetTilat hyväksyväksi tilaksi 6 else merkitse NykyisetTilat hylkääväksi tilaksi 7 for each a Σ 8 do laske SeuraajaTilat kuten algoritmin SimulateNFA riveillä 4 7 9 if tila nimeltä SeuraajaTilat puuttuu tuloksesta M 10 then luo sellainen ja merkitse se uudeksi 11 Lisää tulokseen M siirtymä NykyisetTilat a SeuraajaTilat

Esimerkki Determinisoidaan epädeterministinen automaatti M a a a b a q 0 q 1 q 2 q 3 b b Esimerkiksi tilan s 2 = {q 0, q 2 } seuraaja syötemerkillä a on tila s 3 = {q 0, q 1, q 3 }, sillä s 3 sisältää täsmälleen kaikki joukkoon s 2 kuuluvien alkioiden seuraajat merkillä a: s 3 s 2 a q 0 a q 2 a q 0 q 3 q 1

a a a b a q 0 q 1 q 2 q 3 b b 1. Aloitetaan lisäämällä alkutila {q 0 } ja laskemalla siitä lähtevät siirtymät. a b {q 0 } = s 0 {q 0, q 1 } {q 0 } Jatketaan uudella tilalla {q 0, q 1 }.

a a a b a q 0 q 1 q 2 q 3 b b 2. Lasketaan tilan {q 0, q 1 } siirtymät: Jatketaan uudella tilalla {q 0, q 2 }. a b {q 0 } = s 0 {q 0, q 1 } {q 0 } {q 0, q 1 } = s 1 {q 0, q 1 } {q 0, q 2 }

a a a b a q 0 q 1 q 2 q 3 b b 3. Lasketaan tilan {q 0, q 2 } siirtymät: a b {q 0 } = s 0 {q 0, q 1 } {q 0 } {q 0, q 1 } = s 1 {q 0, q 1 } {q 0, q 2 } {q 0, q 2 } = s 2 {q 0, q 1, q 3 } {q 0 } 4. Saatiin uusi tila {q 0, q 1, q 3 } ja jatketaan sillä...

5.... ja aikanaan saadaan lopputulos: a b {q 0 } = s 0 {q 0, q 1 } {q 0 } {q 0, q 1 } = s 1 {q 0, q 1 } {q 0, q 2 } {q 0, q 2 } = s 2 {q 0, q 1, q 3 } {q 0 } {q 0, q 1, q 3 } = s 3 {q 0, q 1, q 3 } {q 0, q 2, q 3 } {q 0, q 2, q 3 } = s 4 {q 0, q 1, q 3 } {q 0, q 3 } {q 0, q 3 } = s 5 {q 0, q 1, q 3 } {q 0, q 3 } b a a a q 0 a q b 0, q 1 q 0, q 2 a q 0, q 1, q b 3 q 0, q 2, q 3 b a q 0, q 3 b b

Esimerkki Determinisoidaan aakkoston Σ = {M, I, U} seuraava epädeterministinen automaatti: M,I,U M,I,U M I U 0 1 2 3

Ratkaisu: Kun generoidaan koko potenssijoukko eli käytetään suoraa matemaattista määritelmää eikä while-algoritmia niin saadaan tulokseksi: M I U A {0} {0, 1}=E {0}=A {0}=A B {1} {2}=C C {2} {3}=D D {3} {3}=D {3}=D {3}=D E {0, 1} {0, 1}=E {0, 2}=F {0}=A F {0, 2} {0, 1}=E {0}=A {0, 3}=G G {0, 3} {0, 1, 3}=L {0, 3}=G {0, 3}=G H {1, 2} {2}=C {3}=D I {1, 3} {3}=D {2, 3}=J {3}=D J {2, 3} {3}=D {3}=D {3}=D K {0, 1, 2} {0, 1}=E {0, 2}=F {0, 3}=G L {0, 1, 3} {0, 1, 3}=L {0, 2, 3}=M {0, 3}=G M {0, 2, 3} {0, 1, 3}=L {0, 3}=G {0, 3}=G N {1, 2, 3} {3}=D {2, 3}=J {3}=D O {0, 1, 2, 3} {0, 1, 3}=L {0, 2, 3}=M {0, 3}=G jossa S P(Q) ovat saavutettavat tilat ne jotka myös while-algoritmi tuottaisi P(Q) \ S ovat saavuttamattomat tilat ne jotka while-algoritmi jättäisi tuottamatta.

Tulos tilasiirtymäkaaviona johon on piirretty vain saavutettavat tilat: I,U M I,U M I A E F U M U G I L M U I M I,U M M Sama minimoituna: I,U M M,I,U A M I E U M F I U G

Tehtävä Determinisoi seuraava automaatti: a 1 a, b b 2

Esimerkki Determinisoidaan 0 0 a ε c 0 1 1 ε b d 1. Alkutilaksi saadaan E({a}) = {a, c, d}

0 0 2. Alkutilasta päästään tiloihin δ({a, c, d}, 0) = E(δ(a, 0) δ(c, 0) δ(d, 0)) a ε c = E({a, b} {c} ) 0 1 1 ε = E({a, b, c}) = {a, b, c, d} ensimmäinen uusi tila b d δ({a, c, d}, 1) = {d} toinen uusi tila. 3. Käsitellään uudet tilat {a, b, c, d} ja... δ({a, b, c, d}, 0) = {a, b, c, d} δ({a, b, c, d}, 1) = {c, d} sama vanha tila kolmas uusi tila. 4. sitten tila {d}: δ({d}, 0) = δ({d}, 1) = neljäs uusi tila.

0 0 5. Sitten tilan {c, d} seuraajat: a ε c δ({c, d}, 0) = {c, d} sama vanha tila 0 1 1 ε δ({c, d}, 1) = {d} toinen vanha tila. b d 6. Ei enää uusia tiloja; Lopputulos: tila 0 1 {a, c, d} {a, b, c, d} {d} {a, b, c, d} {a, b, c, d} {c, d} {c, d} {c, d} {d} {d} 0 0 0 {a, b, c, d} 1 {c, d} {a, c, d} 1 1 {d} 0 1 0 1

Tehtävä Determinisoi automaatti: b 1 ε a a 2 3 a, b Tehtävä Determinisoi automaatti: ε 1 2 a a a, b 3 b

Hahmonsovituksesta Epädeterministisellä automaatilla voi helposti kuvata hahmonsovitusongelmia: esiintyykö annettu merkkijono y syötteessä x? Mikä tahansa yksittäinen merkkijono (eli yksialkioinen kieli) y = y 1 y 2 y 3... y m Σ voidaan tunnistaa yksinkertaisella epädeterministisellä automaatilla: y 1 y 2 y 3 y m... Σ Σ Kun tällainen automaatti determinisoidaan, tilojen lukumäärä m + 1 ei muutu. (Vrt. edellinen MIU-esimerkki.) Tällaisen epädeterministisen automaatin kaikkia laskentapolkuja voi myös simuloida tehokkaasti, jos m = O(tietokoneen bittisyys eli nykyään 32 tai 64) ns. shift-or/shift-and algoritmilla.

Mutta yleisessä tapauksessa (eli kun kyseessä on mielivaltainen säännöllinen kieli) voi tilojen määrä kasvaa pahimmillaan eksponentiaaliseksi, onhan P(Q) = 2 Q. Toisaalta yksinkertaiselle hahmonsovitusongelmalle osataan muodostaa deterministinen automaatti suoraankin ajassa O(m), ns. Knuth-Morris-Pratt algoritmi.

Ensimmäinen ekskursio: NFA:n simulointi Olkoon pitkä teksti t ja lyhyt merkkijono p ASCII-aakkoston merkkijonoja, ja n = t, m = p, ja m w, missä w on bittien lukumäärä int-muuttujassa (esim. 32 tai 64). Seuraava C-kielinen funktio kertoo kaikki kohdat missä p esiintyy t:ssä. Algoritmi perustuu NFA:n simuloimiseen, ja se toimii ajassa O(n) (nyt kun m w). Yleisesti ottaen mielivaltaisen NFA:n tehokas simuloiminen on kuitenkin avoin ongelma. Miten algoritmi toimii??? Tämä ei kuulu kurssiin. Ongelma on mahdollista ratkaista myös keskimääräisessä ajassa O(n log Σ (m)/m)... void shift_or (char * t, int n, char * p, int m) { unsigned b [256], d = ~0, mm = 1 << (m - 1); int i; } for (i = 0; i < 256; i++) b [i] = ~0 >> (sizeof (int) * 8 - m); for (i = 0; i < m; i++) b [p [i]] &= ~(1 << i); for (i = 0; i < n; i++) { d = (d << 1) b [t [i]]; if ((d & mm)!= mm) printf("löytyi, kohdasta %d\n", i); }

Toinen ekskursio: Knuth Morris Pratt Olkoot edelleen t ja p ASCII aakkoston merkkijonoja, ja n = t, m = p. Seuraava C-kielinen funktio kertoo kaikki kohdat missä p esiintyy t:ssä. Algoritmi perustuu deterministiseen automaattiin. Tässä on kuitenkin ε-siirtymiä, mutta näitä ei seurata jos on toinenkin vaihtoehto, joten haarautumista ei tapahdu... Algoritmi toimii ajassa O(n + m). Miten se täsmällisesti ottaen toimii??? Tämäkään ei kuulu kurssiin. void kmp (char * t, int n, char * p, int m) { int i = 0, j = -1, b [m]; b [i] = j; while (i < m) { while (j >= 0 && p [i]!= p [j]) j = b [j]; b [++i] = ++j; } i = j = 0; while (i < n) { while (j >= 0 && t [i]!= p [j]) j = b [j]; i++; j++; if (j == m) { printf("löytyi, kohdasta %d\n", i); j = b [j]; } } }

Epädeterminismin sovelluksia Näemme pian, että epädeterminismi yksinkertaistaa huomattavasti monia automaattikonstruktioita. Sillä on käyttöä tietojenkäsittelytieteessä laajemminkin, esim. Rinnakkaisjärjestelmät: Asynkronisessa laskennassa eri prosessien suoritusjärjestys ei ole tiukasti kontrolloitavissa. Ajattelemme siis, että suoritusjärjestys määräytyy epädeterministisesti ja vaadimme esim. että järjestelmä ei saa lukkiutua millään suoritusjärjestyksellä. Laskennan vaativuus: Monille tärkeille etsintä- ja optimointiongelmille on helppo esittää epädeterministinen ratkaisu, mutta sen tehokas simuloiminen deterministisellä (eli oikealla) tietokoneella on avoin ongelma. Vrt. edellä: NFA:n muuntaminen DFA:ksi saattaa aiheuttaa tilojen lukumäärän eksponentiaalisen kasvun. (Mutta ei aina, kuten nähtiin.)

Säännölliset lausekkeet ja kielet Säännöllisellä lausekkeella (regular expression) voi kuvailla, minkä muotoisia merkkijonoja hyväksytään. XML-dokumenttien kaavioformalismeissa käytetyt elementtien sisältömallit ovat oleellisesti säännöllisiä lausekkeita. Esim. XHTML-kielen taulukkoelementtien rakennekuvaus: <!ELEMENT table (caption?, (col* colgroup*), thead?, tfoot?, (tbody+ tr+))> XHTML-taulukko voi sisältää alla olevassa järjestyksessä valinnaisen otsikon mielivaltaisen jonon sarake- tai sarakeryhmä-elementtejä valinnaisen ylä- ja alatunnisteen epätyhjän jonon body- tai rivielementtejä.

Tekstinhaku säännöllisillä lausekkeilla Unix-komennolla grep (=global regular expression parser) voidaan etsiä tiedostosta säännöllisellä lausekkeella kuvailtuja rivejä. Esim. Etsi tekstitiedostosta lap.txt rivit, joilla esiintyy sana automaatti : egrep automaatti lap.txt Etsi tekstitiedostosta lap.txt rivit, joilla esiintyy sana automaatti tai sana kieli : egrep \(automaatti\ kieli\) lap.txt Etsi tekstitiedostosta lap.txt rivit, joilla esiintyy äärellinen automaatti tai kahviautomaatti : egrep \(äärellinen \ kahvi\)automaatti lap.txt Etsi tekstitiedostosta tiedosto.txt osoitteita, jotka ovat muotoa... katu tai... tie jota seuraa asunnon numero: egrep [A-ZÅÄÖ][a-zåäö]*\(katu\ tie\) [0-9][0-9]* tiedosto.txt

Monien editoreiden search ja search & replace -komennot sallivat myös säännölliset lausekkeet; samoin jotkut ohjelmointikielet sisältävät regexp kirjastoja. Eräs mahdollisuus grep-toiminnon toteuttamiseksi olisi seuraava: 1. Muodostetaan äärellinen automaatti, joka hyväksyy tasan sellaiset merkkijonot, joissa esiintyy annettu hahmo. 2. Selataan syöte rivi kerrallaan käyttämällä tätä automaattia, ja tulostetaan hyväksytyt rivit. Kysymys: Kuinka monimutkaisia hahmoja tällä periaatteella voidaan käsitellä? Esim. edellä muodostettiin hahmoista automaatti ja kieli uusi hahmo tai-operaattorilla. Samoin sallittiin hahmon iterointi eli katenointi itsensä kanssa ([0-9]*). Kuinka voimakkaat operaattorit voidaan siis sallia?

Kielten yhdiste, tulo ja sulkeuma Olkoot A ja B aakkoston Σ kieliä, eli A, B Σ. Kielten A ja B yhdiste on kieli A B = {x Σ x A tai x B} suoraan joukko-opista. Jos yhdistettä ajattelee eräänlaisena yhteenlaskuna niin sen nolla on koska sen lisäämisellä ei ole vaikutusta: X = X = X.

Kielten A ja B katenaatio eli tulo on kieli AB = {xy Σ x A, y B} eli ne merkkijonot xy jotka alkavat jollakin kielen A merkkijonolla x ja jatkuvat jollakin kielen B merkkijonolla y. Jos tuloa ajattelee eräänlaisena kertolaskuna niin sen ykkönen on {ε} koska Vastaavasti nollalla kertominen nollaa : {ε} X = X {ε} = X. X = X =. Tyhjä kieli ja tyhjä merkkijono ε ovat eri asioita, niillähän on eri tyyppikin. Kielessä {ε} on yksi alkio, nimittäin ε, joten se ei ole tyhjä.

Kielen A potenssit A k, jossa k N, määritellään iteratiivisesti: A 0 = {ε} A k = AA k 1 = AAA... A } {{ } k kertaa = {x 1 x 2 x 3... x k x i A kaikilla i = 1, 2, 3,..., k} (k 1) Kielen A sulkeuma on kieli A = k N A k = {ε} A AA AAA... = {x 1... x k k 0, x i A kaikilla i = 1, 2, 3,..., k} Tässä vihdoin on monissa paikoissä käyttämämme merkinnän potenssiin tarkoitettu sisältö: (...) koostuu niistä merkkijonoista, jota saadaan liimailemalla yhteen äärellisen monta tämän kuvauksen (...) mukaista merkkijonoa.

Erikoistapauksena = {ε}... = {ε} koska nolla(kin) potenssiin nolla on yksi. Esimerkki Tarkastellaan aakkoston {a,... z, 0,..., 9} kieliä A = {aa, bb} ja B = {01, 02}. Nyt A B = {aa, bb, 01, 02} AB = {aa01, aa02, bb01, bb02} A = {ε, aa, bb, aaaa, aabb, bbaa, bbbb, aaaaaa, aaaabb, aabbaa, aabbbb, bbaaaa,...}

Säännöllinen lauseke (syntaksi) Määritelmä Aakkoston Σ säännölliset lausekkeet (regular expressions) määritellään induktiivisesti säännöillä: Vakiot ja ε ovat jokaisen aakkoston säännöllisiä lausekkeita; aakkoston jokainen merkki a Σ on sen säännöllinen lauseke; jos r ja s ovat aakkoston Σ säännöllisiä lausekkeita, niin myös (r s), (rs) ja r ovat sen säännöllisiä lausekkeita; ja muita aakkoston Σ säännöllisiä lausekkeita ei ole.

Säännöllisen lausekkeen merkitys Määritelmä Aakkoston Σ säännöllinen lauseke r kuvaa kielen L(r) Σ : L( ) = L(ε) = {ε} L(a) = {a} kaikilla a Σ L((r s)) = L(r) L(s) L((rs)) = L(r)L(s) L(r ) = (L(r))

Esimerkki Aakkoston {a, b} säännöllisiä lausekkeita ovat esimerkiksi r 1 = ((ab)b), r 2 = (ab), r 3 = (ab ), r 4 = (a(b (bb))). näiden lausekkeiden kuvaamat kielet ovat L(r 1 ) = ({a}{b}){b} = {ab}{b} = {abb}; L(r 2 ) = {ab} = {ε, ab, abab, ababab,...} = {(ab) i i 0}; L(r 3 ) = {a}({b}) = {a, ab, abb, abbb,...} = {ab i i 0}; L(r 4 ) = ({a}{b, bb}) = {ab, abb} = {ε, ab, abb, abab, ababb,...} = {x {a, b} kutakin a-kirjainta x:ssä seuraa 1 tai 2 b-kirjainta }

Lyhennysmerkintäsopimuksia Sulkumerkkejä voidaan vähentää seuraavilla säännöillä: Operaattoreista sitoo vahvimmin, sitten tulo, ja heikoimmin. Yhdiste- ja tulo-operaatioiden assosiatiivisuus: L(((r s) t)) = L((r (s t))) L(((rs)t)) = L((r(st))). Käytetään tavallisia kirjasimia mikäli sekaannuksen vaaraa merkkijonoihin ei ole. Esim. edellisen esimerkin lausekkeet r 1 = ((ab)b), r 2 = (ab), r 3 = (ab ), r 4 = (a(b (bb))) yksinkertaisemmin: r 1 = abb, r 2 = (ab), r 3 = ab, r 4 = (a(b bb)) Lyhennysmerkintä r + tarkoittaa toista r ainakin kerran. Siten r + = rr = r r. Esim. jos d = (0... 9), niin d + (tai dd ) tarkoittaa, että merkkijono koostuu yhdestä tai useammasta numeromerkistä.

Säännöllinen kieli (uudelta kannalta) Voimme määritellä säännöllisen kielen A myös sellaisena, joka voidaan kuvata jollakin säännöllisellä lausekkeella r, eli A = L(r). Osoitamme pian, että tämä on yhtenevää aiemman määritelmämme ( äärellisen automaatin hyväksymä kieli ) kanssa. Esimerkki Olkoon aakkosto Σ = {a, b, c,...}. Säännöllisen lausekkeen Σ automaattiσ kuvaama kieli on niiden merkkijonojen joukko jotka sisältävät osamerkkijonon automaatti. Siis tämä kieli on säännöllinen.

Esimerkki Olkoon Σ = {A, B, C,..., Ö, a, b, c,..., ö, 0, 1, 2,..., 9, }. Osoite on muotoa (Ll )(katu tie) dd (l ε)(dd ε) ddddd Ll jossa d on lyhenne lausekkeelle (0 1 2... 9) l on lyhenne lausekkeelle (a b c... ö) eli pienille kirjamille ( letters ), ja L on lyhenne lausekkeelle (A B C... Ö) eli suurille kirjaimille ( LETTERS ). Huomaa: Monet regexp -kirjastot ja -työkalut lisäävät ominaisuuksia jotka eivät ole säännöllisiä (kuten esimerkiksi rajoittamattomat viitteet taaksepäin, NP-täydellinen ongelma... ). Tällä kurssilla käsitellään vain aitoja säännöllisiä lausekkeita ilman tällaisia lisäyksiä.

Esimerkki Ohjelmointikielen C etumerkittömät liukuluvut (jotka ovat tyyppiä float, double tai long double) määritellään seuraavasti: (kokonaisosa).(desimaaliosa) (e tai E) [+ tai ] (eksponentti) [suffiksi] merkintä [... ] tarkoittaa että kyseinen osa voi myös puuttua kokonaisosa ja desimaaliosa koostuvat numeroista joko kokonaisosa tai desimaaliosa voi puuttua (mutta eivät molemmat) joko (i) desimaalipiste tai (ii) (e tai E) ja eksponentti voivat puuttua (mutta eivät molemmat) suffiksi: F tai f: float, L tai l: long double, muuten double Säännöllinen lauseke (ilman suffikseja): (d +.d.d + )(ε ((e E)(+ ε)d + )) d + (e E)(+ ε)d + Kieleen kuuluvat esim. seuraavat merkkijonot: 12.,.12, 1.2, 1.2E3, 1.2e3, 1E2, 1e23. 1.2E-3,

Tehtävä Tarkastellaan seuraavia aakkoston Σ = {a, b} säännöllisiä lausekkeita. Esitä kunkin lausekkeen kuvaamasta kielestä kaksi merkkijonoa, jotka kuuluvat kieleen, ja kaksi, jotka eivät kuulu kieleen! 1. a b 2. a(ba) b 3. a b 4. (aaa) 5. (ε a)b 6. Σ aσ aσ aσ Tehtävä Etsi lyhyin merkkijono, joka kuuluu seuraavan lausekkeen kuvaamaan kieleen! 1. a (b abb)b b 2. a b b(a (ab) ) b 3. (a ab)(a ab) b

Tehtävä Muodosta seuraavia kieliä vastaavat säännölliset lausekkeet: 1. {w {a, b} w:n kolmanneksi viimeinen merkki on a} 2. {w {a, b} w sisältää joko merkkijonon ab tai ba} 3. {w {a, b} w sisältää parillisen määrän merkkiä a} 4. {w {a, b} w:n pituus on pariton} 5. {w {a, b} w:ssä on 3:lla jaollinen määrä merkkiä b} Tehtävä Esitä yksinkertaisemmassa muodossa seuraavat lausekkeet (eli anna lauseke, joka yhä kuvaa saman kielen, mutta jossa on vähemmän operaattoreita): 1. (0 1 01 11) 2. (0 10 ) 3. 1 (011 ) 1 (011 ) 0

Säännöllisten lausekkeiden sieventäminen Säännöllisillä kielillä on yleensä useita vaihtoehtoisia kuvauksia, esim.: Σ = L((a b) ) = L((a b ) ) = L(a b (a b) ba(a b) ) =... Merkitään r s, kun L(r) L(s), eli kun säännollisen lausekkeen r kuvaama kieli on osa säännöllisen lausekkeen s kuvaamaa kieltä. Säännölliset lausekkeet r ja s ovat ekvivalentit, merkitään r = s, silloin kun r s ja s r, eli kun L(r) = L(s). Lausekkeen sievennys = yksinkertaisimman ekvivalentin lausekkeen määritys. Tässä luonteva yksinkertaisuuden mitta on sen sisältämien operaattoreiden lukumäärä sen pituus kirjoitettuna.

Sievennyssääntöjä I Muistisääntö: on hieman kuin yhteenlasku, ja on hieman kuin 0. Tulo on hieman kuin kertolasku, ja ε on hieman kuin 1.

Sievennyssääntöjä II r r = r (mutta rr r kun r, ε) r (s t) = (r s) t r(st) = (rs)t r s = s r r(s t) = rs rt (r s)t = rt st r = r = r εr = r (mutta ε r = r vain jos ε L(r))

Sievennyssääntöjä III = ε r = r r ε = r + ε r = (r ε) (r ) = r

Tavalliset joukko-operaatiot vs. säännöllisten kielten operaatiot Olkoot A = {a, b} ja B = {c, d}. Joukot Kielet A B = {a, b, c, d} A B = {a, b, c, d} karteesinen tulo A B = tulo AB = {(a, c), (a, d), (b, c), (b, d)} {ac, ad, bc, bd} potenssijoukko P(A) = sulkeuma A = {, {a}, {b}, {a, b}} {ε, a, b, aa, ab, ba, bb, aaa, aab, aba, abb, baa, bab, bba, bbb, aaaa, aaab, aaba, aabb,...} P(X ) = 2 n, kun X = n X =, jos X {ε}

Miten osoittaa, että L(r) = L(s)? Matemaattinen ratkaisutapa on osoittaa, että 1. L(r) L(s) eli r s, ja 2. L(s) L(r) eli s r. Tai helpommin (mutta ehkä työläämmiin) vastaavilla automaateilla: 1. Muodosta lausekkeille r ja s deterministiset automaatit M r ja M s. 2. Tutki hyväksyvätkö automaatit saman kielen. (Tämän voi tehdä joko tutkimalla tuottaako niiden minimointi identtisen tuloksen sivuutamme minimoinnin tai tarkastelemalla niiden ns. tuloautomaattia.) Miten lausekkeesta voidaan muodostaa automaatti?

Säännölliset lausekkeet ja äärelliset automaatit Osoitetaan seuraava tärkeä tulos: 1. Jokaisen säännöllisen lausekkeen r kuvaama kieli voidaan tunnistaa äärellisellä automaatilla M r : Muodostetaan lauseketta r vastaava (epädeterministinen) ε-automaatti. Haluttaessa tämä epädeterministinen automaatti voidaan vielä determinisoida (ja minimoida). 2. Jokaisen äärellisen automaatin M tunnistama kieli L(M) voidaan kuvata säännöllisellä lausekkeella r M : Redusoidaan automaatti 2-tilaiseksi ns. lausekeautomaatiksi, josta voidaan lukea vastaava säännöllinen lauseke.

Säännöllisestä lausekkeesta automaatti Säännöllinen lauseke on käytännöllinen tapa määritellä esim. tekstinhaku- tai tyypintarkistustehtäviä. Miten näin määritelty tehtävä saadaan suoritettua? Lause Säännöllisen lausekkeen kuvaama kieli voidaan tunnistaa äärellisellä automaatilla. Todistus: Annetaan eräs menetelmä, jolla voidaan muodostaa mielivaltaista säännöllistä lauseketta r vastaava ε-automaatti M r, jolla L(M r ) = L(r). (Tämä on ns. Thompson-konstruktio. Muitakin menetelmiä on.)

r = : r = s t: r = ε: ε ε M s ε r = a, a Σ a ε M t ε r = st: r = s : ε M s M t ε M s ε ε Kuva : Säännöllisestä lausekkeesta äärelliseksi automaatiksi.

Esimerkki Muodostetaan säännöllistä lauseketta ((ab ) (b a)) vastaava äärellinen automaatti. a a a b b a, b ε ε ε ε ε ε ε ε ε ε a a ε ε b b ε ε M ab M b a ε ε ε ε ε ε M (ab ) (b a) b

Tehtävä Muodosta säännöllistä lauseketta (0 1) 0 (0 1) 01 = (0 1) (0 01) = (0 1 ) (0 01) vastaava äärellinen automaatti. Tehtävä Muodosta C-kielen liukuluvut tunnistava automaatti säännöllisestä lausekkeesta (d +.d.d + )(ε ((e E)(+ ε)d + )) d + (e E)(+ ε)d + jossa d = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} ovat 10-järjestelmän numeromerkit. Toisaalta ekvivalentti säännöllinen lauseke voidaan esittää monella tapaa, ja osa-automaatit josta lopullinen ratkaisu saadaan voivat olla erilaisia. Eli ratkaisuja on erilaisia (siihen saakka kunnes on determinisoitu ja minimoitu).

Automaatista säännöllinen lauseke Lause Jokainen säännöllinen kieli voidaan kuvata säännöllisellä lausekkeella. Todistus: Esitetään menetelmä, jolla automaatista M voidaan kirjoittaa ekvivalentti säännöllinen lauseke r M, eli jolla L(r M ) = L(M).

Menetelmä toimii poistamalla välitiloja, jotka esiintyvät automaatin alkutilasta lopputilaan johtavilla poluilla. Menetelmän edetessä polku tilasta i tilaan j korvataan oikotiellä eli yhdellä suoralla siirtymällä. Tällaisen oikotien pitää yhä kuvata kaikki samat merkkijonot jotka kerätään kuljettaessa tilasta i tilaan j alkuperäisiä siirtymiä pitkin. r Niinpä oikotie i j nimetään säännöllisellä lausekkeella r, joka kuvaa nämä merkkijonot.

Menetelmässä käytetään siis ns. lausekeautomaatteja, joissa siirtymillä on yksittäisen syötemerkin sijasta kokonainen säännöllinen lauseke r intuitio on, että siirtymässä i j 1. luetaan jäljellä olevan syötteen alusta jokin lausekkeen r mukainen merkkijono, ja 2. jatketaan jäljelle jääneen syötteen loppuosan käsittelyä tilasta j. Tavalliset automaatit ja ε-automaatit ovat lausekeautomaattien erikoistapauksia, koska yksittäiset merkit ja ε ovat myös säännöllisiä lausekkeita. Ohitamme formaalin määritelmän (vaikkei se olekaan hankala).

Olkoon automaatin alkutila s. Yksinkertaistetaan käsittelyä olettamalla, että automaatilla on täsmälleen yksi lopputila, josta lisäksi ei lähde siirtymiä eikä se myöskään ole alkutila s. (Jos näin ei ole, korvataan vanhat lopputilat yhdellä uudella, johon lisätään ε-siirtymät vanhoista lopputiloista. Ks. kuva.) ε ε f ε Kuva : Lopputilojen korvaaminen yhdellä uudella.

Oikoteiden muodostaminen: 1. Poistetaan ensin kaikki rinnakkaiset siirtymät: Jos on kaksi samojen tilojen välistä p q p q siirtymää i j ja i j, korvaa ne yhdellä yhteisellä siirtymällä i j kuten kuvassa. Selvästi tämä säilyttää samoina ne merkkijonot, jotka kerättäisiin kulkemalla näitä siirtymiä pitkin solmusta i solmuun j. p i j = i p q j q Kuva : Kaksi rinnakkaista siirtymää yhdeksi.

2. Sitten poistetaan automaatista välitilat: Sanotaan, että tila k s on välitila, tila i sen edeltäjä ja tila j sen seuraaja, jos p automaatissa on siirtymät i i r j k ja k j, ja k i, j. (Edeltäjä ja seuraaja voivat kuitenkin keskenään olla sama tila.) Millaisia merkkijonoja pitää välitilan k ohittavan oikopolun i R i,j j hyväksyä? V: Niitä, joiden alkuosa hyväksytään kaarella (i, k) ja loppuosa kaarella (k, j). p i.r j Lähtökohtaisesti saadaan siis suora siirtymä i j. Jos välitilasta k on lisäksi silmukkasiirtymä k q k takaisin itseensä, tällaista voidaan kulkea mielivaltaisen monta kertaa. Tällöin oikopoluksi tulee kuten kuvassa. i p i.q.r j j (2)

Jos välitilan edeltävän i ja seuraajan j välillä oli jo suora siirtymä i oikopolun lauseke lisätään siihen uutena vaihtoehtona: tai (jos välitilalla oli silmukkasiirtymä) i i r i,j j, niin r i,j p i r j j (3) r i,j p i q r j j (4) Jos välitilan edeltäjä ja seuraaja ovat sama tila, niin oikopolku on silmukkasiirtymä.

Kun välitilalle on muodostettu oikopolku sen jokaisesta edeltäjästä sen jokaiseen seuraajaan, niin tämä välitila k ja kaikki siihen liittyvät siirtymät voidaan poistaa. Kun rinnakkaiset siirtymät ja välitilat on poistettu, niin: Automaatissa on jäljellä sen alkutila s ja lopputila f. Jos alkutilasta ei ole siirtymää lopputilaan, automaattia vastaava lauseke on : Alkuperäisessä automaatissa ei ole millään syötteellä lopputilaan johtavaa polkua. r Muussa tapauksessa redusoidussa lausekeautomaatissa on siirtymä s f. Jos tilasta s on lisäksi silmukka s lauseke alkaa iteraatiolla q. Tällöin tulos on q s takaisin itseensä, tunnistettua kieltä kuvaava q r (5) Jos tällaista alkutilan silmukkaa ei ole, niin sitä vastaava osa q jää pois lopputuloksesta (5).

q i. p i k r j. j p i q r j Kuva : Oikotie välisolmun k ohi.

q r s r f q Kuva : Lauseke kutistuneesta automaatista.

Esitetään tämä menetelmä vielä algoritmina: 1 Lisää kuvan mukainen uusi hyväksyvä tila f ellei sellaista jo ole p q 2 while on rinnakkaiset siirtymät i j ja i j 3 do korvaa ne yhdellä siirtymällä i p q j 4 while on välitiloja s, f 5 do k jokin (mikä tahansa) välitila p i 6 for each siirtymä i k jossa i k 7 do for each siirtymä k r j j jossa j k q 8 do if on siirtymä k k 9 then t p i q r j 10 else t p i r j 11 u if on siirtymä i j 12 then päivitä se muotoon i 13 else lisää siirtymä i t j u t j 14 poista tila k ja kaikki nämä siihen liittyvät siirtymät 15 r if on siirtymä s f 16 q then if on siirtymä s s 17 then return q r 18 else return r 19 else return

Otetaan esimerkki tästä menetelmästä: (i) alkuperäinen automaatti: (ii) lisätään uusi lopputila: 0 0 0 0 0 0 s 1 s 1 1 1 1 (iii) yhdistetään rinnakkaiset: 1 1 ε 1 f (iv) poistetaan tila: ε s 1 0 1 0 1 s 1 0 1 0 1 ε f ε 0 1 ε (0 1)ε f

(v) poistetaan tila: (vi) poistetaan tila: s 1 (0 1)(ε (0 1)ε) s 1(0 1)(ε (0 1)ε) 0 1 Nyt voidaan lukea lopputulos f 0 1 f (0 1) 1(0 1)(ε (0 1)ε) jota voidaan vielä hieman sieventää muotoon (0 1) 1(0 1)(ε 0 1) josta voidaan lukea vastaus: alkuperäinen automaatti hyväksyy ne binäärijonot, joiden toiseksi tai kolmanneksi viimeinen merkki on 1. Lausekkeita voi ja kannattaakin sievennellä jo menetelmän aikana.

Tehtävä Muodosta seuraavan automaatin tunnistamaa kieltä kuvaava säännöllinen lauseke: a, b 1 2 a a b 3 b

Säännöllisten kielten sulkeumaominaisuudet Matematiikassa sanotaan että joukko X on suljettu jonkin operaation suhteen, jos soveltamalla operaatiota joukon X alkioihin saadaan tulokseksi aina joukon X alkioita eli jos operaatio ei vie pois joukosta X. Esimerkiksi luonnollisten lukujen joukko N on suljettu yhteenlaskun suhteen, koska m + n N jokaisella m, n N. Se ei kuitenkaan ole suljettu vähennyslaskun suhteen, koska esimerkiksi 5 8 N, vaikka 5, 8 N. Tarkastellaan säännöllisten kielten joukkoa (s.o. merkkijonojoukkojen joukkoa). Minkälaisten operaatioiden suhteen se on suljettu?

Lause Olkoot L 1 ja L 2 aakkoston Σ säännöllisiä kieliä. Tällöin myös seuraavat ovat säännöllisiä kieliä: yhdiste L 1 L 2 leikkaus L 1 L 2 katenaatio eli tulo L 1 L 2 komplementti L 1 = Σ \ L 1 erotus L 1 \ L 2 (Kleenen) sulkeuma (L 1 ) käänteiskieli (L 1 ) R = {w R w L 1 } eli kielen L 1 merkkijonot takaperin kirjoitettuina. Toisin sanoen säännöllisten kielten joukko on suljettu kaikkien näiden operaatioiden suhteen. Todistus: Perustellaan alla.

Huomaa että lause on yksisuuntainen: Esimerkiksi yhdiste L 1 L 2 voi olla säännöllinen, vaikka sen osat L 1 ja L 2 eivät ole. Esimerkiksi säännöllinen kieli voidaan muodostaa osista ja L(a b ) = L 1 L 2 L 1 = {a i b j i j} L 2 = {a i b j i > j} joista kumpikaan ei ole säännöllinen (mikä voidaan osoittaa pumppauslemmalla ).

Sulkeuma säännöllisten operaattoreiden suhteen Sännölliset kielet nähdään helposti suljetuiksi säännöllisten lausekkeiden operaattoreiden suhteen: Olkoot A ja B säännöllisiä kieliä, eli A = L(p) ja B = L(q) joillain säännöllisillä lausekkeilla p ja q. Tällöin A B = L((p q)) AB = L((pq)) ja A = L(p ) Kukin on ilmaistavissa säännöllisellä lausekkeella, eli kukin on säännöllinen kieli.

Sulkeuma komplementoinnin suhteen Esimerkki Laaditaan automaatti, joka tunnistaa kielen L(M) = {w {a, b} w ei sisällä merkkijonoa bab}. Laaditaan ensin deterministinen automaatti, joka tunnistaa sen komplementtikielen L(M) = {w {a, b} w sisältää merkkijonon bab}. Haluttu automaatti saadaan vaihtamalla hyväksyvät tilat hylkääviksi ja päinvastoin. a b a,b a b a,b b a b 0 1 2 3 b a b 0 1 2 3 a a Huom: virhetilojen on oltava mukana, koska niistä tulee hyväksyviä tiloja. Sama voidaan tehdä jokaiselle säännölliselle kielelle.

Muistutus: De Morganin säännöt Tuttuja koulumatematiikasta tai diskreeteistä rakenteista tai matemaattisesta logiikasta. Ilmaisevat joukko-opissa, että komplementointi kääntää yhdisteet leikkauksiksi ja päinvastoin: A B = A B A B = A B. Osoitetaan näiden nojalla, että säännöllisten kielten A ja B leikkaus on säännöllinen: 1. A B = A B 2. De Morgan: A B = A B 3. Säännöllisten kielten komplementteina A ja B ovat säännöllisiä. 4. Siten myös niiden yhdiste A B on säännöllinen, ja samoin sen komplementti. Säännölliset kielet nähdään edellisen nojalla suljetuiksi myös joukkoerotuksen suhteen, kun lähdetään liikkeelle tiedosta A \ B = A B.

Säännöllisten kielten leikkaus/yhdiste/erotus automaatilla Vaihtoehtoisesti säännöllisten kielten A ja B joukko-opillinen yhdistelmä L (yhdiste, leikkaus tai erotus) voidaan tunnistaa ns. tuloautomaatilla. Olkoot M 1 = (Q 1, Σ, δ 1, q 1, F 1 ) ja M 2 = (Q 2, Σ, δ 2, q 2, F 2 ) deterministiset automaatit, joilla A = L(M 1 ) ja B = L(M 2 ). Muodostetaan uusi automaatti M, jonka tiloja ovat alkuperäisten automaattien tilojen parit (p, q) Q 1 Q 2 siirtymäfunktio δ muodostuu komponenttitilojen siirtymistä: δ ((p, q), a) = (δ 1 (p, a), δ 2 (q, a)) lopputilat F valitaan sen mukaan mitä joukko-operaatiota toteutetaan: Jos L = A B, niin F = {(p, q) p F 1 tai q F 2 } Jos L = A B, niin F = {(p, q) p F 1 ja q F 2 } Jos L = A \ B, niin F = {(p, q) p F 1 ja q F 2 }.

Säännöllisen kielen käänteiskieli Miksi säännöllisen kielen L käänteiskieli (L) R olisi säännöllinen? Olkoon M = (Q, Σ, δ, q 0, F ) kielen L tunnistava DFA. Kuten aiemmin, voidaan olettaa (sallimalla ε-siirtymiä), että automaatilla on yksikäsitteinen lopputila f. Muodostetaan käänteiskielen hyväksyvä NFA M asettamalla sen alkutilaksi f ja lopputilaksi q 0 ja kääntämällä automaatin M siirtymät päinvastaisiksi. Formaalisti automaatin M siirtymäfunktio δ : Q (Σ {ε}) P(Q) määräytyy säännöllä δ (q, a) := {p Q δ(p, a) = q}.

Säännöllisten kielten rajoituksista Kysymys: Kuinka voidaan havaita, ettei ongelma ratkeakaan äärellisillä automaateilla? Eli ettei vastaava formaalikieli olekaan säännöllinen?

Esimerkki Onko sisäkkäisten sulkulausekkeiden muodostama kieli L ( ) = {( k ) k k 0} säännöllinen? Yritetään tehdä sille automaatti: ( ( ( ( q 0 q 1 q n 1 q n ) ) ) ) q 2n q 2n 1 q n+2 q n+1 ) ( ( ( ( q 0 q 1 q n 1 q n ) ) ) ) Mutta entäpä jos sisäkkäisiä sulkupareja onkin n + 1 kpl?

Automaattien rajallinen muisti Ääärellinen automaatti muistaa syötteen alkuosan vain tilojensa avulla. Se ei siis voi pitää kirjaa kaikista näkemistään merkeistä. Ääretön kieli voi olla säännöllinen vain jos siinä on jokin toistuva rakenne. Automaatissa silmukka, säännöllisessä lausekkeessa sulkeuma (...). Säännöllisten kielten pumppauslemma formalisoi tämän havainnon. Kielen osoittaminen säännölliseksi ei ole laskennallisesti ratkeava ongelma, vaan siihen tarvitaan ihmisen matemaattista intuitiota on keksittävä sille automaatti tai lauseke tai todistettava se sulkeumaominaisuuksien avulla säännöllisiksi tiedetyistä kielistä tai...

Saattaa näyttää ilmeiseltä, että äärellisen muistin ajatuksen soveltaminen olisi jotenkin intuitiivisesti selvää, eli että muistivaatimukset näkisi jotenkin suoraan. Kieli A = {w {0, 1} w sisältää yhtä monta nollaa ja ykköstä} ei ole säännöllinen (todistetaan pian... ). Mutta kieli onkin säännöllinen. B = {w {0, 1} w:ssä esiintyy 01 ja 10 yhtä monta kertaa} Tehtävä Todista että tämä kieli B on säännöllinen. Vihje: Mieti millä merkillä jono w B voi alkaa ja millä loppua.

Lause Kieltä C = {0 n 1 n n N} ei voi tunnistaa äärellisellä automaatilla. Todistus: Osoitetaan, että vastaoletuksesta C = L(M) jollain äärellisellä automaatilla M seuraa ristiriita: Olkoon M vastaoletuksen mukainen automaatti ja siinä k = Q tilaa, ja m = k/2. Koska L(M) = C, niin silloin myös syöte s = 0 m 1 m L(M). Tämän syötteen s pituus s = 2m k. Merkitään sen merkkejä s = s 1 s 2... s 2m. Syötteellä s automaatti käy yhteensä 2m + 1 tilassa, mukaan lukien alkutila (joista osa (tai kaikki) voivat olla samoja). Toisin sanoen, automaatti käy tiloissa: r 1 0 r2 0 0 rm+1 1 rm+2 1 1 r2m+1. Eli alkutila q 0 = r 1 ja δ(r i, s i ) = r i+1, missä r i Q. Havainto: Q = k < 2m + 1 joten jonossa r 1... r 2m+1 ainakin yksi tila esiintyy useammin kuin kerran, eli r i = r j jollain i < j.

Automaatti tekee merkkijonolla s i... s j 1 silmukan tilasta r i takaisin tilaan r i = r j : x = s 1... s i 1 r i = r j z = s j... s 2m r 1 r 2m+1 y = s i... s j 1 Automaatti siis hyväksyy alkuperäisen jonon s = xyz = xy 1 z kiertämällä silmukan yhden kerran. Merkitään vastaavaa hyväksyvää laskentaa lyhyesti: r 1 x ri y ri z r2m+1.

Silmukan sisältävästä hyväksyvästä laskennasta saadaan uusi hyväksyvä laskenta ohittamalla silmukka: r 1 x ri z r2m+1 Siis automaatti hyväksyy myös merkkijonon xy 0 z = xz. Silmukkaa voidaan myös toistaa mielivaltaisen monta kertaa: r 1 x ri y ri y ri z r2m+1. r 1 x ri y ri y ri y ri z r2m+1. Siis automaatti hyväksyy myös merkkijonot xy 2 z = xyyz, xy 3 z = xyyyz, xy 4 z = xyyyyz,... Kysymys: Kuuluuko merkkijono xy l z kieleen C = {0 n 1 n mahdollisella toistokertojen lukumäärällä l N? n N} jokaisella

Tarkastellaan silmukan mahdollisia sijainteja merkkijonon s keskikohdan suhteen: x = s 1... s i 1 r 1 r i = r j r 2m+1 z = s j... s 2m 1. i < j m + 1: nyt y = 0 j i. 2. i < m + 1 < j: nyt y = 0 m+1 i 1 j m 1. 3. m + 1 i < j: nyt y = 1 j i. y = s i... s j 1 Missään näistä tapauksista esimerkiksi xy 2 z ei kuulu kieleen C: tapauksessa 1 siinä on liikaa nollia tapauksessa 2 se on muotoa 0... 01... 10... 01... 1 tapauksessa 3 siinä on liikaa ykkösiä.

Koska automaatti kuitenkin hyväksyy merkkijonon xy 2 z, tämä on ristiriita oletuksen C = L(M) kanssa. Siis kieltä C ei voi tunnistaa k-tilaisella äärellisellä automaatilla millään k, eli kieli C ei ole säännöllinen.

Edellisen todistuksen perusidea oli osoittaa, että jos M on k-tilainen automaatti, niin kielellä L(M) on pumppauspituus k: Määritelmä Kielellä A on äärellinen pumppausominaisuus, jos on olemassa sellainen p, että mikä tahansa s A, jolla s p, voidaan esittää muodossa s = xyz, missä 1. xy i z A kun i = 0, 1, 2,..., 2. y > 0 ja 3. xy p. Tällöin p on (eräs) kielen A pumppauspituus. Siis x = ε ja z = ε ovat sallittuja, mutta y ε (ehto 2, koska muuten pumpattavuus olisi triviaalia). Kun kielellä on äärellinen pumppausominaisuus, millä tahansa riittävän pitkällä merkkijonolla s on epätyhjä keskiosa y, jota pumppaamalla saadaan uusia kieleen kuuluvia merkkijonoja xy 2 z, xy 3 z,...

Lause (Säännöllisten kielten pumppauslemma) Jokaisella säännöllisellä kielellä on äärellinen pumppausominaisuus. Todistus: Sivuutetaan; vastaava kuin edellisen lauseen todistuksessa. Intuitiivisesti: Äärettömän säännöllisen kielen tunnistavassa automaatissa on silmukka siten, että 1. xy i z A: silmukka voidaan kiertää mielivaltaisen monta (i) kertaa, ja silti voidaan päästä jonolla z hyväksyvään tilaan. 2. y > 0: silmukka ei ole tyhjä, vaan siihen kuuluu vähintään yksi ei-tyhjä siirtymä. 3. xy p: laskennan täytyy joutua silmukkaan ennen kuin automaatista loppuvat tilat. x = s 1... s i 1 r i = r j z = s j... s 2m r 1 r 2m+1 y = s i... s j 1

Pumppautuvuusehto 1 tarkoittaa, että kieli sisältää merkkijonot xz, xyz, xyyz, xyyyz,... Ehdosta 2 seuraa, että nämä jonot ovat toinen toistaan pidempiä. Siis merkkijonoa y pumppaamalla saadaan rajattomasti uusia kieleen kuuluvia merkkijonoja. Ehdon 3 nojalla tämä osajono y löytyy sanan s alkuosasta, jonka pituus on p. Kielen pumppautuvuus tarkoittaa, että jokainen tarpeeksi pitkä kieleen kuuluva merkkijono on pumppautuva jollain ehdot täyttävällä osajonollaan y.

Pumppauslemman soveltaminen Kiinnostavaa vain äärettömille kielille (äärelliset kielet ovat aina säännöllisiä). Pumppauslemman mukaan millä tahansa säännöllisellä kielellä A on pumppausominaisuus, toisin sanoen jollakin p N mille tahansa sellaiselle s A joka on riittävän pitkä eli s p on olemassa jako s = xyz jolla pumppausehdot 1 3 toteutuvat. Pumppauslemmalla ei voi osoittaa kielen säännöllisyyttä, vain ei-säännöllisyyden. (Eikä aina sitäkään, koska on olemassa ei-säännöllisiä kieliä, joilla on äärellinen pumppauspituus... ) Ideana todistus kontrapositiolla, eli lemmaa käytetään käänteisesti ; A on säännöllinen A on pumpattavissa A ei ole pumpattavissa A ei ole säännöllinen

Toisin sanoen, on osoitettava, että mille tahansa p N on olemassa sellainen s A, että s p ja mille tahansa sen jaolle s = xyz jokin pumppausehdoista 1 3 jää toteutumatta. Siis aluksi voimme itse valita sanan s sopivasti helpottamaan todistusta, mutta sitten meidän pitää käydä läpi kaikki mahdolliset tavat jakaa se osiin x, y ja z ja osoittaa, että mikään jako ei toteuta pumppausehtoja. Toisin sanoen, kun halutaan todistaa kieli ei-säännölliseksi, tehdään vastaoletus että se olisikin säännöllinen, ja osoitetaan että tästä seuraa ristiriita...... jonka voi osoittaa käyttämällä pumppauslemmaa...... mutta jonka voi osoittaa muutenkin: Esimerkiksi sulkeumaominaisuuksien avulla ( palautetaan ongelma tunnettuun kieleen).

Esimerkki Kieli C = {0 n 1 n Todistus: n N} ei ole säännöllinen. Tehdään vastaoletus että C olisikin säännöllinen. Silloin sillä olisi äärellinen pumppausominaisuus, eli jokin vakio p siten, että jokainen ainakin niin pitkä merkkijono s C (eli s p) jakautuu jotenkin osiin s = xyz jotka täyttävät ominaisuuden 3 ehtoa. 1. xy i z C kun i = 0, 1, 2,..., 2. y > 0 ja 3. xy p. Me emme tiedä vakion p arvoa, mutta me saamme valita sellaisen merkkijonon s kuin haluamme (kunhan valitsemme tarpeeksi pitkän). Kun olemme valinneet merkkijonomme s, niin me emme tiedä sen jaosta s = xyz muuta kuin nämä 3 ominaisuutta. Koska tavoittelemme ristiriitaa, niin useimmiten kannattaa valita s siten, että ehdot 2 ja 3 ovat voimassa, ja osoittaa että silloin ehtoa 1 ei enää saadakaan voimaan.

Tässä todistuksessa kannattaa valita s = 0 p 1 p (tai jokin vielä pidempi) koska silloin ehdot 2 ja 3 kertovat meille paljon osien xy rakenteesta: jossa k > 0 mutta j + k p. x = 0 j y = 0 k z = 0 p (j+k) 1 p Koska tämä järkeilymme ei oleta näistä arvoista j ja k mitään muuta, niin olemme tulleet käyneeksi läpi samalla kertaa kaikki mahdolliset jaot. Nyt ehdon 3 mukaan (vaikkapa) i = 0 kertaa pumpattu merkkijono 0 j 0 p (j+k) 1 p = 0 p k 1 p C. Mutta toisaalta kielen C määritelmän mukaan pitäisi olla koska k > 0. samalla merkkijonolla 0 p k 1 p C Tässä on etsimämme ristiriita joka todistaa, että vastaväite olikin väärin, eli että alkuperäinen väite olikin oikein.

Pumppauslemman ohella käytössämme ovat myös säännöllisten kielten sulkeumaominaisuudet ja muut säännöllisiksi ja ei-säännöllisiksi tunnetut kielet. Esimerkki Osoita, että D = {w {0, 1} w sisältää yhtä monta nollaa ja ykköstä} ei ole säännöllinen. Todistus: Tehdään taas vastaoletus: D on säännöllinen. Kieli 0 1 on selvästi säännöllinen (joko kuvaavan lausekkeensa tai tunnistavan automaattinsa kautta). Siten kieli (0 1 ) D on säännöllinen (tunnettu sulkeumaominaisuus). Tämä on ristiriita, koska (0 1 ) D on sama kuin C = {0 n 1 n on aiemmin todistettu ei-säännölliseksi. n N}, joka

Esimerkki Osoita (toistamiseen), että kieli D = {w {0, 1} w sisältää yhtä monta nollaa ja ykköstä} ei ole säännöllinen. Todistus: Tehdään jälleen se vastaoletus että D on säännöllinen. Edetään tällä kertaa pumppauslemmalla: Valitaan s = 0 p 1 p. Olkoon s = xyz D, missä y ε ja xy p. Nyt y koostuu yhdestä tai useammasta nollasta. Koska xyz D, niin xyyz sisältää nollia enemmän kuin ykkösiä, joten xyyz D. Ristiriita. Miten valitaan sopiva s? Jos olisi valittu s = (01) p, ei olisi saatu ristiriitaa, koska tätä voidaan pumpata (esim. x = ε, y = 01, z = (01) p 1 ). Pitäisi siis keksiä (sille tuntemattomalle) automaatille hankalia tapauksia.

Heuristisia ohjeita ei-säännöllisyystodistuksiin Mikä ominaisuus tekee kielen ei-säännölliseksi?. Usein ominaisuus koskee kahta sanan osaa, joiden välillä vallitsee jokin ehto. Tämä ominaisuus voi koskea esim. tiettyjen merkkien lukumäärien keskinäistä suhdetta, esim. L 1 = {a k b m c m k, m = 0, 1, 2,...} L 2 = {a m b 2m m = 0, 1, 2,...} sanan eri osia, esim. sanan alku- ja loppuosa riippuvat jotenkin toisistaan: L 3 = {ww R w Σ } L 4 = {ww w Σ }.

Mikä on yksinkertaisin, mielivaltaisen pituinen merkkijono, jossa tämä ominaisuus esiintyy? Joskus kielessä on todistuksen kannalta täysin turhia (säännöllisiä) osia, esim. kielessä L 1 merkin a lukumäärällä ei ole mitään väliä voidaan valita merkkijono b m c m. Mutta jos ehdon osapuolten välissä on tuollainen säännöllinen osa, se saattaa olla tarpeen osapuolien erottamiseen toisistaan, esim. kielessä L 5 = {a m b k a m m, k = 0, 1, 2,...} tarvitaan ainakin yksi b erottamaan alkuosan ja loppuosa merkit a. Valitaan esim. a m ba m. Jos kielen alku- ja loppuosa riippuvat jotenkin toisistaan, mutta muuten ne saavat olla mitä tahansa, riittää erottaa alku- ja loppuosa toisistaan. Esim. kielen L 4 kohdalla voidaan valita a m ba m b tai ba m ba m.

Valitse sana s siten, että pumpattava osajono y kuuluu sen ensimmäiseen p merkkiin. Testaa kaikki pumppauslemman mukaiset jaot s = xyz, xy p ja y ε. Jokaisella jaolla kokeile pumppausta kierroslaskurin i arvoilla 0, 2, 3,... kunnes löytyy sellainen arvo i, että xy i z ei kuulu kieleen yleensä i = 0 tai i = 2 riittää. Tutkittavien tapausten vähentämiseksi kannattaa valita sana s siten, että sen erilaisia jakoja osiin xyz olisi mahdollisimman vähän. Tätä käytimme todistaessamme, että kieli C = {0 n 1 n n N} ei ole säännöllinen: valitsimme merkkijonon s niin pitkäksi, että alkuosa x ja pumppautuva osa y olivat molemmat 0-jonoja.

Säännöllisten kielten luokka on suljettu (erityisesti) leikkauksen ja komplementin suhteen. On annettu kieli A, joka pitäisi osoittaa ei-säännölliseksi. Valitaan jokin säännöllinen kieli B, Jos nyt A B ei ole säännöllinen, niin myöskään A ei ole säännöllinen. (On kuitenkin oltava tarkkana, esim. kahden ei-säännöllisen kielen leikkaus voi olla säännöllinen.) Jos A (komplementti) on ei-säännöllinen, niin myös A on ei-säännöllinen. Voidaan siis soveltaa pumppauslemmaa kieliin C = A B tai D = A mutta jos C tai D on jokin tunnetusti ei-säännöllinen kieli, erillistä pumppauslemma-todistusta ei tarvita.

Pikakertaus: tähän mennessä... Deterministinen äärellinen automaatti (DFA): yksinkertainen laskentalaite, muistia vain vakiomäärä, syötteen pituudesta riippumatta. Säännölliset kielet: niiden kielten luokka, joka voidaan tunnistaa DFA:lla. Epädeterministinen äärellinen automaatti (NFA): kieli voidaan tunnistaa DFA:lla jos ja vain jos se voidaan tunnistaa NFA:lla. NFA on hyödyllinen kuvausformalismi. DFA voi vaatia eksponentiaalisesti enemmän tiloja kuin NFA. Kieli voidaan tunnistaa DFA:lla jos ja vain jos se voidaan kuvata säännöllisellä lausekkeella. Kaikki kielet eivät ole säännöllisiä. Pumppauslemmaa voidaan käyttää kielen epäsäännöllisyyden osoittamiseen. Eräs esimerkki ei-säännöllisestä kielestä on {w {a, b} w = w R }

Tähän mennessä: säännölliset kielet, tunnistus äärellisellä automaatilla Seuraavaksi: kontekstittomat kielet, tunnistus pinoautomaatilla Myöhemmin (LAT-kurssilla): kontekstilliset ja rekursiiviset kielet: tunnistus Turingin koneella ( tietokoneella ) Kaikki muut kielet: vain osittain ratkeavia ( kyllä -tapauksessa) tai täysin ratkeamattomia.

ratkeamattomat ongelmat tyyppi 0: rajoittamattomat kielet rekursiivisesti lueteltavat kielet tunnistus: universaali Turingin kone (pysähtyy "kyllä" tapauksessa) rekursiiviset kielet tunnistus: Turingin kone + riittävän mittainen työnauha (pysähtyy aina), RAM kone, ohjelmointikielet tyyppi 1: kontekstiset kielet tunnistus: Turingin kone + kohtuullisen (eli polynomisen) mittainen työnauha tyyppi 2: kontekstittomat kielet tunnistus: pinoautomaatti tyyppi 3: säännölliset kielet; tunnistus: äärellinen automaattivakiomäärä muistia äärelliset kielet

Koetehtäviä? Yleisesti, samantyylisiä kuin luentojen esimerkit ja kotitehtävät. Perustehtäväprototyyppi: Tehtävä Laadi DFA / NFA joka tunnistaa kielen X. Determinisoi automaatti käyttäen luennoilla annettua menetelmää. Mikä on automaattia / kieltä vastaava säännöllinen lauseke? Muunna säännöllinen lauseke automaatiksi tai automaatti lausekkeeksi käyttäen luennoilla annettua menetelmää. Jne...

Soveltavampaa: Tehtävä Säännöllinen kieli A voidaan tunnistaa deterministisellä äärellisellä automaatilla M A. Kielen A komplementtikieli A voidaan tunnistaa automaatilla M A, joka saadaan automaatista M A vaihtamalla hyväksyvät tilat ei-hyväksyviksi, ja ei-hyväksyvät hyväksyviksi. Toisin sanoen säännöllisten kielten luokka on suljettu komplementin suhteen. Edelleen, olkoon M A epädeterministinen automaatti, joka tunnistaa kielen A. Voidaanko automaatista M A vaihtaa hyväksyvien ja ei-hyväksyvien tilojen roolit edellä kuvatulla tavalla, ja saada tulokseksi epädeterministinen äärellinen automaatti joka tunnistaa kielen A? Onko epädeterminististen automaattien tunnistamien kielten luokka suljettu komplementoinnin suhteen?

Tehtävä Miten mielivaltaisesta NFA:sta saadaan NFA jossa on vain yksi hyväksyvä tila? Tehtävä Voiko säännöllistä kieltä 0 1 tunnistaa deterministisellä äärellisellä automaatilla, jossa on vain yksi hyväksyvä tila? Perustele. Tehtävä Osoita, että säännöllisten kielten luokka on suljettu leikkauksen suhteen. Tehtävä Olkoon A säännöllinen kieli. Osoita, että myös A R = {w R w A} on säännöllinen. Tehtävä Olkoot kielet A ja B säännöllisiä. Onko kieli C = A B = (A B) (B A) säännöllinen? (Siis w C, jos w kuuluu joko kieleen A tai B, mutta ei molempiin.) Perustele.

Tehtävä Mitkä seuraavat aakkoston Σ = {a, b} kielistä ovat säännöllisiä? 1. E = {a n a n n N} 2. F = {wuw R w, u Σ + } 3. G = {ww w Σ } 4. H = {a i b j i j}

Kontekstittomat kielet ja pinoautomaatit Kontekstittomat kielet (context-free languages, yhteydettömät kielet) voidaan kuvata kontekstittomilla kieliopeilla (context-free grammar) ja tunnistaa epädeterministisillä pinoautomaateilla (pushdown automaton). Verrattuna edelliseen lukuun, korvaamme säännölliset lausekkeet näillä kieliopeilla, ja epädeterministiset äärelliset automaatit näillä pinoautomaateilla. Pinoautomaatti on kuten äärellinen automaatti, johon on lisätty rajoittamattoman suuri muisti. Tämä muisti on TRA-kurssilta tuttu pino (stack). Tämä rajoittamattoman suuri muisti tarkoittaa, että pino-operaatiot eivät koskaan jumiudu virheilmoitukseen Out Of Memory Error.

Tavoitteet: Opitaan mitä ovat kontekstittomat kielet ja pinoautomaatit, ja mikä on niiden välinen suhde. Opitaan muodostamaan kielioppi yksinkertaisille kontekstittomille kielille. Opitaan jäsentämisen perusideat.

Johdatteleva esimerkki: Miten kuvaisit seuraavat kielet? Sisäkkäisten sulkulausekkeiden kieli: L ( ) = { ( k ) k k 0 } { } if else-parien muodostama kieli: L if-else = if k else l l k Ne eivät ole säännöllisiä, joten säännöllisillä lausekkeilla se ei onnistu. Ratkaisuyritys: Annetaan kielelle L ( ) rekursiivinen kuvaus: Merkitään S = mielivaltainen sisäkkäinen sulkulauseke. Tällöin S on sisäkkäinen sulkulauseke, jos 1. S = ε tai 2. S on muotoa (S ), missä myös S on sisäkkäinen sulkumerkkijono. Toinen kuvaustapa (ensimmäinen kontekstiton kielioppimme): 1. S ε 2. S (S) Esimerkiksi merkkijonon ((())) tuottaminen: S (S) ((S)) (((S))) (((ε))) = ((()))

Vastaava jäsennyspuu (tähän palataan vielä): S S S ( ( ( ε ) ) )

Kontekstittoman kieliopin idea Joukko muuttujasymboleita ja muunnossääntöjä tämän muuttujan esiintymän saa korvata tuolla merkkijonolla joka voi vuorostaan sisältää uusia muuttujasymbolien esiintymiä. Yksi näistä muuttujasymboleista on erityinen aloitussymboli. Muunnetaan merkkijonoa näillä säännöillä, kunnes siinä ei enää esiinny muuttujasymboleita. Näin on tuotettu lopullinen merkkijono.

Esimerkki Yksinkertainen kielioppi aritmeettisille lausekkeille: E T E + T T F T F F a (E). Esimerkiksi ensimmäinen rivi luetaan muuttujasymboli E voidaan korvata merkkijonolla T tai merkkijonolla E + T jossa T on toinen muuttujasymboli ja + merkki. Se tuottaa vaikkapa aritmeettisen lausekkeen (a + a) a seuraavasti: E T T F F F (E) F (E + T ) F (T + T ) F (F + T ) F (a + T ) F (a + F ) F (a + a) F (a + a) a Kussakin vaiheessa on korvattu alleviivattu muuttujasymbolin esiintymä.

Kontekstittoman kieliopin formaali määritelmä Määritelmä Kontekstiton kielioppi on nelikko jossa G = (V, Σ, P, S) äärellinen joukko V on kieliopin aakkosto; Σ V on kieliopin päätemerkkien joukko; sen komplementti N = V \ Σ on kieliopin välikemerkkien eli -symbolien joukko (joita edellä kutsuimme muuttujasymboleiksi); äärellinen joukko P N V on kieliopin sääntöjen eli produktioiden joukko; ja S N on kieliopin lähtösymboli. Sääntöä (A, ω) P merkitään A ω. Sen voi lukea välike A voi tuottaa/johtaa merkkijonon ω.

Intuitiivisesti kontekstiton kielioppi G = (V, Σ, P, S) tuottaa merkkijonoja Σ seuraavalla epädeterministisellä algoritmilla: 1 r S 2 while r sisältää välikesymboleja 3 do valitse jokin A N (siis vaikka ensimmäinen tai viimeinen) jonosta r = αaβ, missä α V on sitä ennen tuleva osa, ja β V on sen jälkeen tuleva osa 4 valitse jokin välikkeen A sääntö A ω P 5 r αωβ 6 tulosta näin saatu r Silloin kieliopin G tuottama formaali kieli L(G) muodostuu merkkijonoista r, jotka tämä algoritmi voi tulostaa valitsemalla säännöt sopivasti rivillään 4.

Kontekstittoman kielen formaali määritelmä Merkkijono αaβ V, jossa A N, voi tuottaa tai johtaa suoraan merkkijonon αωβ V, jos kieliopissa G on sääntö A ω P. Tätä merkitään Esimerkiksi sekä että αaβ G αωβ T F G F F T F G T a esimerkin kieliopissa G aritmeettisille lausekkeille.

Merkkijono γ 0 V, voi tuottaa tai johtaa merkkijonon γ n V, jos on olemassa jono merkkijonoja V siten, että γ 0 γ 1 γ 2 γ n G G G G eli jos merkkijono γ 0 voi tuottaa suoraan merkkijonon γ 1 joka voi tuottaa suoraan merkkijonon γ 2 joka voi tuottaa suoraan merkkijonon... joka voi tuottaa suoraan merkkijonon γ n. Tätä merkitään γ 0 γ n G Esimerkiksi aritmeettisten lausekkeiden kieliopilla G pätee T F (E) a G

koska siinä voidaan johtaa T F G F F G (E) F G (E) a. Erikoistapauksena jokainen merkkijono γ V voi tuottaa itsensä eli γ γ G tyhjällä jonolla (jossa n = 0). Esimerkiksi T F T F. G

Merkkijono γ V on kieliopin G lausejohdos, jos γ voidaan johtaa sen lähtösymbolista S: S γ. G Esimerkiksi (E) a ja (a + a) a ovat lausejohdoksia esimerkin kieliopissa aritmeettisille lausekkeille. Kieliopin G lause on sen pelkistä päätemerkeistä koostuva lausejohdos: S γ ja γ Σ. G Esimerkiksi (a + a) a on lause esimerkin kieliopissa aritmeettisille lausekkeille.

Kieliopin G tuottama tai kuvaama kieli koostuu sen lauseista: { } L(G) = γ Σ S γ. G L(G) on siis kaikkien niiden lauseiden (merkkijonojen) joukko, jotka voidaan tuottaa kieliopilla G aloittamalla sen lähtösymbolista S. Määritelmä Formaali kieli L Σ on kontekstiton, jos se voidaan tuottaa jollakin kontekstittomalla kieliopilla.

Kontekstista Sana konteksti (englanniksi context ) on suomeksi lauseyhteys. Siten sanan kontekstiton tilalla käytetäänkin joskus sanoja yhteydetön tai yhteysvapaa. Kontekstiton viittaa siihen, että kieliopin säännöt ovat muotoa A ω, mikä voidaan tulkita siten, että muuttuja A voi tuottaa merkkijonon ω, olipa sen ympärillä mitä tahansa.

Kontekstittoman kieliopin yleistys on konteksti(lli)nen kielioppi (context-sensitive grammar). Tällaisen kieliopin säännöt ovat muotoa αaβ αωβ jossa α, β V ja ω V +. Tällainen sääntö tulkitaan siten, että muuttuja A voidaan korvata (epätyhjällä) merkkijonolla ω jos sen edessä on α ja perässä β eli jos A on lauseyhteydessä jotakinαaβmuuta niin silloin siitä voidaan johtaa jotakinαωβmuuta. Lisäksi voidaan sallia produktio S ε, jotta kielioppi voi hyväksyä myös tyhjän merkkijonon.

Esimerkiksi kieli {a n b n c n n N} ei ole kontekstiton, mutta se voidaan esittää käyttämällä kontekstisia sääntöjä. Kontekstisia kielioppeja ei käsitellä tällä kurssilla. Nekin ovat silti kiintoisia... automaattien teoriassa: Kuten jo vihjattiin, kontekstittomat kielet voidaan tunnistaa automaateilla joilla on tavallinen pino. Kontekstiset taas automaateilla joilla on avopino. laskennan vaativuusteoriassa: Kontekstiset kielet ovat ne, jotka voidaan tunnistaa käyttämällä realistinen eli polynominen määrä muistia.

Jos sallitaan rajoittamattomat produktiot α β, missä α V + ja β V, niin saadaan rajoittamattomat kieliopit, joilla voidaan kuvata kaikki algoritmisesti generoitavissa olevat kielet.

ratkeamattomat ongelmat tyyppi 0: rajoittamattomat kielet rekursiivisesti lueteltavat kielet tunnistus: universaali Turingin kone (pysähtyy "kyllä" tapauksessa) rekursiiviset kielet tunnistus: Turingin kone + riittävän mittainen työnauha (pysähtyy aina), RAM kone, ohjelmointikielet tyyppi 1: kontekstiset kielet tunnistus: Turingin kone + kohtuullisen (eli polynomisen) mittainen työnauha tyyppi 2: kontekstittomat kielet tunnistus: pinoautomaatti tyyppi 3: säännölliset kielet; tunnistus: äärellinen automaattivakiomäärä muistia äärelliset kielet

Vakiintuneita merkintätapoja Välikesymboleita merkitään isoilla kirjaimilla: A, B, C,..., S, T Päätemerkkeinä käytetään pieniä kirjaimia a, b, c,..., s, t; numeromerkkejä 0, 1,..., 9; erikoismerkkejä; varattuja sanoja kuten if,for,end,... lihavoituina tai alleviivattuina. Mielivaltaisina merkkeinä (kun välikkeitä ja päätemerkkejä ei erotella) käytetään X, Y, Z. Päätemerkkijonoina käytetään u, v, w, x, y, z. Sekamerkkijonoina käytetään α, β, γ,..., ω.

Kielioppi esitetään usein pelkkänä sääntöjoukkona: A 1 ω 11... ω 1k1 A 2 ω 21... ω 2k2. A m ω m1... ω mkm Tällöin välikesymbolit päätellään joko edellisten merkintäsopimusten mukaan tai siitä, että ne esiintyvät sääntöjen vasempina puolina lähtösymboli on ensimmäisen säännön vasempana puolena esiintyvä välike; tässä siis A 1.

Esimerkki Sisäkkäisten sulkujonojen muodostaman kielen L ( ) = {( k ) k k 0} tuottaa kielioppi G ( ) = ({S, (, )}, {(, )}, {S ε, S (S)}, S) Esimerkki Tasapainoisten sulkujonojen muodostaman kielen tuottaa kielioppi G ( ) = ({S, (, )}, {(, )}, {S ε, S (S), S SS}, S) Esimerkiksi ()(()) on tasapainoinen muttei sisäkkäinen sulkujono. Tämän mahdollistaa uuden säännön lisäämisen edellisen esimerkin kielioppiin.

Esimerkki Kielen {a i b k c k i, k = 0, 1,...} voi tuottaa kieliopilla G = (V, Σ, P, S), jossa V = {S, A, B, a, b, c} Σ = {a, b, c} P = {S AB, A aa, A ε, B bbc, B ε}.

Esimerkki Yksinkertaisten aritmeettisten lausekkeiden muodostaman kielen L expr tuottaa kielioppi jossa V = {E, T, F, a, +,, (, )}, Σ = {a, +,, (, )}, G expr = (V, Σ, P, E) (6) P = {E T, E E + T, T F, T T F, F a, F (E)}.

Kieliopilla G expr voidaan johtaa esim. seuraavat lausejohdokset: P : 1. E T 2. E E + T 3. T F 4. T T F E E + T T F + T a F + T a (T ) + T T + T F F + T a (E) + T a (F ) + T 5. F a a (a) + T a (a) + F 6. F (E) a (a) + a

Toinen kielioppi kielen L expr tuottamiseen on G expr = (V, Σ, P, E), (7) jossa V = {E, a, +,, (, )}, Σ = {a, +,, (, )}, P = {E E + E, E E E, E a, E (E)}

Esimerkki XML-dokumenttien kaavioformalismit kuten DTD (Document Type Definition) muistuttavat kontekstittomia kielioppeja. Dokumenttikaavio kuvaa dokumentin elementtirakennetta, joka näkyy sen XML-koodauksessa käytettävistä elementtitunnisteista (eli tägeistä ) kuten <lasku> ja </lasku> alla: <lasku><asiakas><etunimi>kalle</etunimi> <sukunimi>könönen</sukunimi> </asiakas> <tuote><nimi>suksi</nimi><hinta>99</hinta><lkm>2</lkm></tuote> <tuote><nimi>pitoteippi</nimi><hinta>5</hinta><lkm>1</lkm></tuote> </lasku>

Dokumenttikaavioiden välikesymboleina käytetään elementtien nimiä kuten alla: <!ELEMENT lasku (asiakas, tuote+)> <!ELEMENT asiakas (etunimi, sukunimi, osoite?)> <!ELEMENT tuote (nimi, hinta, lkm)> Validi elementti on tällöin sitä vastaavan välikesymbolin tuottama lause. Elementtisisällölle tyypillinen valinnaisuus ja toisto kuvataan säännöllisillä lausekkeilla. Sikäli dokumenttikaaviot muistuttavat ns. laajennettuja kontekstittomia kielioppeja (ECFG), joiden produktiot voivat samoin sisältää säännöllisiä lausekkeita. Oleellisin ero kontekstittomiin kielioppeihin: Kontekstittomat kieliopit kuvaavat merkkijonoja. Dokumenttikaaviot sitä vastoin kuvaavat konkreettisen tekstiesityksen sijasta hierarkkista elementtirakennetta. Siten dokumenttikaaviot vastaavat pikemmin ns. säännöllisiä puukielioppeja, joita vastaavat laskentamallit ovat ns. puuautomaatteja.

Esimerkki Tarkastellaan suomen kielen virkettä, joka koostuu yksinkertaisesta päälauseesta sekä nollasta tai useammasta sisäkkäisestä relatiivilauseesta: L rel = {subj (joka pred attr obj) pred attr obj} Tällaisia virkkeitä voidaan tuottaa esim. seuraavilla kontekstittoman kieliopin G rel VIRKE SUBJ SL PRED ATTR OBJ SL joka PRED ATTR OBJ SL ε säännöillä: SUBJ poika tyttö jänis susi peikko PRED pelkäsi metsästi ATTR suurta pientä vihaista hirmuista arkaa OBJ poikaa tyttöä jänistä sutta peikkoa

Mitä virkkeitä voit johtaa lähtösymbolista VIRKE? Esimerkiksi: VIRKE SUBJ SL PRED ATTR OBJ peikko SL PRED ATTR OBJ peikko joka PRED ATTR OBJ SL PRED ATTR OBJ peikko joka PRED ATTR OBJ SL metsästi ATTR OBJ peikko joka PRED ATTR OBJ SL metsästi hirmuista OBJ peikko joka PRED ATTR OBJ SL metsästi hirmuista jänistä peikko joka pelkäsi ATTR OBJ SL metsästi hirmuista jänistä peikko joka pelkäsi vihaista OBJ SL metsästi hirmuista jänistä peikko joka pelkäsi vihaista tyttöä SL metsästi hirmuista jänistä peikko joka pelkäsi vihaista tyttöä metsästi hirmuista jänistä. Kontekstittomat kieliopit ovat luontaisia positionaalisille kielille, jossa kuka teki mitä kenelle ilmaistaan niiden paikoilla lauseessa. Esimerkiksi englannin kielessä on sanajärjestys on valtaosin subjekti-verbi-objekti (SVO) kuten yllä. Mutta suomen kielessä sanajärjestys onkin vapaa ja kuka teki mitä kenelle ilmaistaankin sijamuodoilla.

Esimerkki Ohjelmointikielten syntaksin kuvaus. Pascalin osajoukko: lause ehtolause koottu-lause sijoitus kutsu ehtolause if ehto then lause else lause ehto x=0 koottu-lause begin lausejono end lausejono lause lause ; lausejono sijoitus x:=0 kutsu a b c Tästä on hyötyä ohjelmoijalle (syntaksi pitää osata, jos aikoo ohjelmoida), mutta myös kääntäjä (tai yksi sen osa, jäsennin (englanniksi parser )) voidaan laatia suoraviivaisesti perustuen kielioppiin. Jäsennystä edeltää yleensä selausvaihe, jossa ohjelman lähdekoodi pilkotaan yllä kuvattuihin osiin ( varatut sanat, muuttujat, aliohjelmien nimet, vakiot, jne) käyttäen äärelliseen automaattiin perustuvaa transduktoria.

Tehtävä Laadi kontekstiton kielioppi, joka tuottaa rajattoman monista sisäkkäisistä for-silmukoista, alkeisoperaatioista a ja kokonaislukuvakioista N koostuvat ohjelmointikielen lauseet, kuten for (i=n; i<n; i++) { for (j=n; j<n; j++) { a } }

Muita sovelluksia ovat esimerkiksi pseudotiedettä suoltava puppugeneraattori http://pdos.csail.mit.edu/scigen/...

... sekä kasvikieliopit (nimeltään L- eli Lindenmayer-systeemit): Niiden ideana on mallintaa sitä biologista kontrollimekanismia, joka määrää, että tähän kohtaan kasvaa uusi oksa, tuohon kohtaan taas uusi lehti. Vastaavantapaisia, hyödyllisempiä, sovelluksia on muitakin, kuten neuroverkkojen rakenteen generointi kieliopilla (joka on voitu generoida vaikkapa geneettisillä algoritmeilla), yms.