T-79.148 Kevät 2003 Tietojenkäsittelyteorian perusteet Harjoitus 8 Demonstraatiotehtävien ratkaisut 4. Tehtävä: Laadi algoritmi, joka testaa onko annetun yhteydettömän kieliopin G = V, Σ, P, S) tuottama kieli epätyhjä, so. voidaanko kieliopin lähtösymolista S johtaa yhtään päätejonoa x Σ. Vastaus: Allaoleva proseduuri?generatesnonemptylanguageg) ottaa syötteenä yhteydettömän kieliopin G, ja palauttaa arvon true, jos G:n generoima kieli ei ole tyhjä.?generatesnonemptylanguageg = V, Σ, P, S): context-free grammar) T Σ repeat V Σ times for each A X 1 X k P if A T X 1 X k T k T T {A} if S T return true else return false Algoritmin idea on lähteä terminaalisymolien joukosta Σ ja testata, onko näistä mahdollista perääntyä S:ään käyttäen joukon P produktioita käänteisesti. Perääntymistä simuloidaan iteroimalla V Σ kertaa saavutettavien symolien joukkoa T. Perusteluksi sille, että V Σ askelta riittää, tarkastellaan sanaa z LG), jolla on kielen sanoista kaikkein pienin jäsennyspuu. Jos z:lla on muotoa S uay uvaxy uvwxy oleva johto, missä u, v, w, x, y Σ, niin myös sana z = uwy voidaan johtaa kieliopin säännöillä 1. Tällöin kuitenkin z :n jäsennyspuu on pienempi kuin z:n jäsennyspuu, mikä on ristiriidassa sen oletuksen kanssa, että z:n puu on pienin. Tästä seuraa se, että missään z:n minimaalisen jäsennyspuun haaroissa ei voi esiintyä sama välike kahteen kertaan, joten algoritmissa riittää käydä sääntöjoukko läpi yhtä monta kertaa kuin kieliopissa on välikkeitä. Tarkastellaan esimerkiksi kielioppia: S A AA A aas a S c Algoritmin laskenta etenee joukon T osalta seuraavasti: T 0 = {a,, c} T 1 = {a,, c, } c) T 2 = {a,, c, A, } T 3 = {a,, c, A,, C} A a) S A, S AA) Koska V Σ = 3, algoritmin suoritus päättyy ja T = T 3. Huomataan, että S T, joten kieli ei ole tyhjä. Pienin kieleen kuuluvan sanan jäsennyspuu on: 1 Vertaa yhteydettömien kielten pumppauslemmaan. 1
S A c c c 5. Tehtävä: Muodosta kielioppia G = V, Σ, P, S) vastaava pinoautomaatti, kun V = {S,, ),,,, a, } Σ = {, ),,,, a, } P = {S SS), S S, S S S), S, S a, S } Vastaus: Mitä tahansa yhteydetöntä kielioppia G = V, Σ, R, S) vastaava epädeterministinen pinoautomaatti M = Q, Σ, Γ, δ, q 0, F ) voidaan laatia seuraavasti: Q = {q 0, q 1, q acc } Γ = V { } F = {q acc } δ = { q 0, ε, ε), q 1, S ) ), q 1,, ε), q acc, ε) ) } 1) { q 1, ε, A), q 1, α) ) A α) P } 2) { q 1, σ, σ), q 1, e) ) σ Σ} 3) Tässä symolia käytetään pinon pohjan merkkinä. Tehtävän kieliopille konstruktio tuottaa seuraavan pinoautomaatin: Q ={q 0, q 1, q acc } Σ ={, ),,,, a, } Γ ={S,, ),,,, a,, } F ={q acc } δ = { q 0, e, e), q 1, S ) ), q 1,, e), q acc, e) ), q 1, e, S), q 1, SS)) ), q1, e, S), q 1, S ) ), q 1, e, S), q 1, S S)) ), q 1, e, S), q 1, ) ), q1, e, S), q 1, a) ), q 1, e, S), q 1, ) ), q1,, ), q 1, e) ), q 1, ), )), q 1, e) ), q 1,, ), q 1, e) ), q1,, ), q 1, e) ), q 1,, ), q 1, e) ), q 1, a, a), q 1, e) ), q1,, ), q 1, e) )} Syntynyt automaatti on muotoa: ε, A/α ε, ε/s ε, /ε q 0 q 1 q acc σ, σ/ε Tarkastellaan, miten automaatti käsittelee syötteen a ): 2
Tila Syöte Pino Sääntö q 0 a ) ε q 1 a ) S 1) q 1 a ) S S) 2) S S S)) q 1 a ) S S) 3) q 1 a ) a S) 2) S a) q 1 ) S) 3) q 1 ) S ) 2) S S ) q 1 ) ) 2) S ) q 1 ) ) 3) q 1 ) ) 3) q 1 ε 3) q acc ε ε 1) Huom. kieli LG) määrittelee kaikki syntaktisesti oikeanmuotoiset aakkoston Σ = {a, } yli muodostetut säännölliset lausekkeet. 6. Tehtävä: Muodosta pinoautomaattia M vastaava kielioppi, missä M = Q, Σ, Γ, δ, s, F ): Q ={s, q, f} Σ ={a, } Γ ={a,, c} F ={f} δ = { s, e, e), q, c) ), q, a, c), q, ac) ), q, a, a), q, aa) ) q, a, ), q, e) ), q,, c), q, c) ), q,, ), q, ) ) q,, a), q, e) ), q, e, c), f, e) )} Vastaus: Tilakaaviona M näyttää seuraavalta: s a, c/ac a, a/aa a, /ε ε, ε/c ε, c/ε q, c/c, /, a/ε f Pinoautomaattia vastaavan yhteydettömän kieliopin selvittäminen on suhteellisen työlästä. Tässä käytetään algoritmia, jotka toimii vain yksinkertaisille pinoautomaateille. Pinoautomaatti on yksinkertainen, mikäli seuraavat ehdot toteutuvat: Jos q, u, β), p, γ) ) on pinoautomaatin siirtymä, niin β 1. Jos q, u, e), p, γ) ) δ, niin myös q, u, A), p, γa) ) δ kaikille A Γ. Rajoitukset eivät kuitenkaan heikennä pinoautomaattien ilmaisuvoimaa, sillä mikä tahansa pinoautomaatti voidaan muuttaa yksinkertaiseksi yksityiskohdat sivuutetaan tässä). Kieliopin muodostamisen ajatuksena on ottaa kielen välikkeiksi kolmikkoja q, A, p, missä q, p Q ja A Γ {ε}. Ajatuksena on, että q, A, p generoi kaikki ne merkkijonot, joita tutkiessaan automaatti siirtyisi tilasta q tilaan p poistaen samalla pinosta symolin A. Kieliopin sääntöjä on neljänlaisia: 3
1. Kaikille f F asetetaan sääntö S s, ε, f. 2. Kaikille siirtymille q, u, A), r, 1 n ) ) δ, missä q, r Q, u Σ, n > 0, A Γ {ε} ja 1 n Γ, lisätään sääntö kaikille p, q 1,..., q n 1 Q. q, A, p u r, 1, q 1 q 1, 2, q 2 q n 1, n, p 3. Kaikille siirtymille q, u, A), r, ε) ) δ, missä q, r Q, u Σ ja A Γ {ε}, lisätään sääntö q, A, p u r, ε, p 4. Kaikille q Q lisätään sääntö q, ε, q ε. Säännöistä ensimmäinen ilmaisee, että tarkoituksena on päästä alkutilasta johonkin lopputilaan niin, että pino jää lopuksi tyhjäksi. Viimeistä muotoa olevat säännöt kertovat, että mitään laskentaa ei tarvita, ellei siirrytä toiseen tilaan. Muotoa 2 olevat säännöt kuvaavat pitkää suoritusta, jolla siirrytään tilasta q tilaan p ja samalla poistetaan A pinosta. Säännön oikea puoli konstruoi automaatin tilasiirtymien jonon siirtymä kerrallaan. Muotoa 3 olevat säännöt ovat analogisia muotoa 2 olevien sääntöjen kanssa. Kielioppi G = V, Σ, P, S), V = Σ {S} { q, A, p q, p Q, A Γ {ε}} P ={S s, e, f, 1.) s, ε, s ε, q, ε, q ε, f, ε, f ε, 4.) s, ε, s ε q, c, s, s, ε, q ε q, c, q, s, ε, f ε q, c, f, q, c, s a q, a, s s, c, s q, c, q a q, a, q q, c, q q, c, f a q, a, f f, c, f q, a, s a q, a, s s, a, s q, a, q a q, a, q q, a, q q, a, f a q, a, f f, a, f q,, s a q, ε, s q,, q a q, ε, q q,, f a q, ε, f q, c, s q,, s s, c, s q, c, q q,, q q, c, q q, c, f q,, f f, c, f q,, s q,, s s,, s q,, s q,, q q,, q q,, s q,, f f,, f q, a, s q, ε, s q, a, q q, ε, q q, a, f q, ε, f q, c, s ε f, ε, s q, c, q ε f, ε, q q, c, f ε f, ε, f 2./tr.1) 2./tr.1) 2./tr.1) 2./tr.2) 2./tr.2) 2./tr.2) 2./tr.3) 2./tr.3) 2./tr.3) 3./tr.4) 3./tr.4) 3./tr.4) 2./tr.5) 2./tr.5) 2./tr.5) 2./tr.6) 2./tr.6) 2./tr.6) 3./tr.7) 3./tr.7) 3./tr.7) 3./tr.8) 3./tr.8) 3./tr.8) 4
Näistä säännöistä suuri osa on tarpeettomia. Tarvittavat saadaan selville lähtemällä liikkeelle säännöstä S s, ε, f, ja katsomalla, mitä kaikkia sääntöjä voidaan käyttää. Tuloksena syntyvät säännöt ovat P = {S s, ε, f s, ε, f q, c, f q, c, f a q, a, q q, c, f q, c, f q,, q q, c, f q, c, f f, ε, f q, a, q a q, a, q q, a, q q, a, q q, ε, q q,, q q,, q q,, q q,, q a q, ε, q q, ε, q ε f, ε, f ε} Kielioppia voi vielä sieventää. Merkitään q, c, f = S, q,, q =, q, a, q = A, ja tulokseksi saadaan Liite: Chomskyn normaalimuoto P = {S aas S ε A aaa, a} Muutetaan viimeisen tehtävän kielioppi Chomskyn normaalimuotoon. Kielioppi on Chomskyn normaalimuodossa, mikäli seuraavat ehdot toteutuvat: 1. Ainoastaan alkuvälike S voi olla tyhjentyvä. 2. Mahdollisesti esiintyvää sääntöä S ε lukuunottamatta kaikki säännöt ovat muotoa A C tai A a, missä A, ja C ovat välikkeitä ja a terminaalisymoli. Kielioppi muutetaan normaalimuotoon vaiheittain: 1. Poistetaan lähtösymoli sääntöjen oikealta puolelta. Koska kieliopissa on säännöt S aas ja S S, lisätään uusi lähtösymoli S ja sääntö S S. Saadaan tulokseksi sääntöjoukko: S S, S aas S ε A aaa, a 2. Poistetaan ε-produktiot. Koska Chomskyn normaalimuodossa ainoastaan lähtösymoli S saa olla tyhjentyvä, täytyy muut ε-säännöt poistaa kieliopista. Lasketaan aluksi tyhjentyvien välikkeiden joukko NULL: NULL 0 ={S} S ε) NULL 1 ={S, S } S S) NULL 2 ={S, S } = NULL 5
Tämän jälkeen korvataan säännöt A X 1 X n joukolla sääntöjä { X i, X i / NULL A α 1 α 2, missä α i = X i tai ε, X i NULL Lopuksi poistetaan kaikki säännöt muotoa A ε lukuunottamatta sääntöä S ε). Saadaan tulokseksi sääntöjoukko 2 : S S ε S aas aa S A aaa, a 3. Poistetaan yksikköproduktiot. Seuraavaksi poistetaan kieliopista kaikki muotoa A olevat säännöt, missä sekä A että ovat välikkeitä. Lasketaan ensin joukot F A) kaikilla A V Σ: F A) = F ) = F S) = F S ) = {S} Välike kuuluu joukkoon F A) täsmälleen silloin, kun A:sta voidaan johtaa käyttäen pelkkiä yksikköproduktioita. Sääntö A korvataan sääntöjoukolla {A w C F ) {} : C w P }. Tulokseksi saadaan sääntöjoukko: S aas aa S ε S aas aa S A aaa, a 4. Poistetaan liian pitkät produktiot. Viimeisessä vaiheessa lisätään kielioppiin uusi välike C σ sekä sääntö C σ σ kaikille σ Σ sekä jaetaan kaikki säännöt A w w > 2) ketjuksi sääntöjä, jotka kaikki johtavat tismalleen kaksi symolia. Annetun kieliopin Chomskyn normaalimuodoksi saadaankin seuraava sääntöjoukko: S C a S 1 C a A C S 2 C ε S 1 AS S 2 S S C a S 1 C a A C S 2 C S 1 AS S 2 S A C a A 1 A 1 AA C a 1 a 1 C a a C 2 Tarkkaan ottaen tässä vaiheessa pitäisi lisätä vielä uusi aloitusvälike S ja säännöt S ε S, mutta tässä tapauksessa ei synny ongelmia, vaikka käytetään S :a lähtösymolina. 6
Liite: CYK-algoritmi CYK-algoritmilla voidaan tutkia kuuluuko sana x = x 1 x n kieliopin G määrittelemään kieleen. Algoritmin kuluessa lasketaan välikejoukot N ik. Joukko N ik käsittää kaikki ne välikkeet, joista voidaan johtaa osajono x i x i+k, eli sanan x kohdasta i alkava k:n merkin mittainen osajono. Joukkojen laskemisessa voidaan käyttää apuna dynaamista ohjelmointia seuraavaan tapaan: Tarkastellaan kielioppia G: N i,1 = {A A x i ) P } k 1 N i,k = {A V Σ G:ssä on sääntö A C, j=1 missä N ij ja C N i+j,k j } S C a D C a A C a E C a A C a D C a A a C a E C D AC E C C a a C Tarkistetaan, kuuluvatko sanat w 1 = aa ja w 2 = aa kieleen LG). Koska w 2 on w 1 :n prefiksi, täytyy taulukko tehdä ainoastaan sanalle w 1. Lasketaan ensin joukot N i1, i 5: i 1 : a 2 : a 3 : 4 : 5 : k 1 aa aa aa aa aa {S, A, C a } {S, A, C a } {S,, C } {S,, C } {S,, C } Kussakin taulukon ruudussa on alleviivattuna ruutua vastaava sanan osajono. Lasketaan seuraavaksi N 12, eli niiden välikkeiden joukko, jolla voidaan johtaa sanan alussa oleva aa. Koska normaalimuotoisessa kieliopissa ei ole yhtään sääntöä, jolla voisi suoraan johtaa useamman kuin yhden terminaalisymolin, voidaan aa saada ainoastaan siten, että johdetaan jostain välikkeestä kaksi a:n tuottavaa välikettä. Käytännössä tämä tapahtuu siten, että etsitään kaikki sellaiset välikkeet X, joille on olemassa sääntö X Y Z, missä Y N 11 ja X N 21. N 11 = {S, A, C a } N 21 = {S, A, C a } N 12 = {S, A}. Tässä käytettiin sääntöjä S C a A ja A C a A. Ruudulle N 22 saadaan vastaavasti: N 21 = {S, A, C a } N 31 = {S,, C } N 22 = {D}. Ainoa ehdot täyttävä sääntö on D AC. Kokonaisuudessaan taulukon toiseksi riviksi muodostuu: i 1 : a 2 : a 3 : 4 : 5 : 1 aa aa aa aa aa {S, A, C a } {S, A, C a } {S,, C } {S,, C } {S,, C } k 2 aa aa aa aa {S, A} {D} {S,, E} {S,, E} 7
Ruudun N 13 kohdalla huomataan, että sanan kolme ensimmäistä merkkiä aa) voidaan johtaa kahdella eri tavalla: 1. johdetaan a välikkeellä X N 11 ja a välikkeellä Y N 22 ; tai 2. johdetaan aa välikkeellä X N 12 ja välikkeellä Y N 31. Vastaavat joukot ovat: j = 1 N 11 = {S, A, C a } j = 2 N 12 = {S, A} N 22 = {D} N 31 = {S,, C } Tapausta j = 1 vastaava välikejoukko on {S, A} S C a D, A C a D) ja tapausta j = 2 vastaava on {D} D AC ), joten N 13 = {S, A, D}. Samaan tapaan jatkamalla saadaan lopulta koko taulukoksi: i 1 : a 2 : a 3 : 4 : 5 : 1 aa aa aa aa aa {S, A, C a } {S, A, C a } {S,, C } {S,, C } {S,, C } 2 aa aa aa aa {S, A} {D} {S,, E} {S,, E} k 3 aa aa aa {A, S, D} {S, } {S,, E} 4 aa aa {S,, E} 5 aa {S, } Viimeisessä vaiheessa täytyi käydä läpi neljä eri kominaatiota: N 11, N 24 ), N 12, N 33 ), N 13, N 42 ) sekä N 14, N 51 ). Koska S N 15, niin aa LG). Toisaalta, koska S / N 1,4, niin aa / LG). Taulukosta voidaan konstruoida suoraan sanan w 1 jäsennyspuu käymällä se läpi takaperin: S saadaan ruutuun N 15 ruuduista N 11 ja N 24 käyttäen välikkeitä C a ja E, joten ensimmäisenä käytetään sääntöä S C a E. Ylläolevassa taulukossa on sanan w 1 johdossa käytetyt välikkeet alleviivattu. Kokonaisuudessaan jäsennyspuu on seuraavanlainen: S C a E a C C a E a C 8