Rekursiiviset palautukset [HMU 9.3.1] Yleisesti sanomme, että ongelma P voidaan palauttaa ongelmaan Q, jos mistä tahansa ongelmalle Q annetusta ratkaisualgoritmista voidaan jotenkin muodostaa ongelmalle P ratkaisualgoritmi. Palauttaminen, epäformaalisti ymmärrettynä, on keskeinen väline normaalissa ohjelmoinnissa jne: 1. Halutaan ratkaista ongelma P. 2. Kirjoitetaan ongelman P ratkaiseva ohjelma p, joka kutsuu aliohjelmaa q (esim. sort). Aliohjelmasta q oletetaan, että se ratkaisee tunnetun ongelman Q (esim. järjestää taulukon), mutta sen toteutuksesta ei sanota vielä mitään. 3. Aliohjelma p on nyt ongelman P palautus ongelmaan Q. 4. Jos jostain kirjastosta löydetään ongelmalle Q ratkaisualgoritmi (esim. quicksort), saadaan ratkaisu myös ongelmalle P. 111
Tällä kurssilla palautuksia käytetään lähinnä väärään suuntaan osoittamaan ongelmia ratkeamattomiksi: 1. Halutaan osoittaa, että ongelma Q on ratkeamaton. 2. Palautetaan jokin tunnetusti ratkeamaton ongelma P (esim. L d ) ongelmaan Q, ts. osoitetaan miten mistä tahansa ongelman Q ratkaisualgoritmista saataisiin ongelman P ratkaisualgoritmi. 3. Koska oletuksen mukaan kuitenkin P on ratkeamaton, myöskään ongelmalle Q ei voi olla ratkaisualgoritmia. Seuraavaksi määritellään palautuksen käsite täsmällisesti, tarkastellaan esimerkkejä edellä esitetyn tyyppisistä todistuksista ja samalla laajennetaan tunnettujen ratkeamattomien ongelmien kirjastoa, josta saadaan kandidaatteja ongelmaksi P. 112
Ruvetaan nyt määrittelemään palautuksen käsitettä täsmällisemmin. Idea: Määritellään laskennallisten ongelmien relaatio A B, ongelma A voidaan palauttaa ongelmaan B Intuitiivinen tulkinta: Kun A B niin B on ainakin yhtä vaikea kuin A, eli ongelma A voidaan ratkaista ongelman B avulla. Tyypillinen käyttötapa: Halutaan osoittaa ongelma B vaikeaksi. Valitaan jokin vaikeaksi tunnettu A, ja osoitetaan A B. Huomaa palautuksen suunta! Huom. kurssikirja ei määrittele palautukselle merkintää A B, mutta käytämme sitä tässä koska se on vakiintunut ja helpottaa asioiden esittämistä. 113
Palautus voidaan formalisoida monella tavalla. Määrittelemme seuraavaksi yksinkertaisen ns. many-one-palautuksen, jota merkitään m. Johdatteleva esimerkki: Tunnetusti kaikilla x, y R pätee joten e x e y = e x+y, a b = exp(ln a + ln b). Olkoon siis r: R 2 R, r(a, b) = ab. Nyt r = ψ s φ, missä φ(a, b) = (ln a, ln b), s(x, y) = x + y ja ψ(z) = e z. Yleisemmin kun näin pätee, sanomme että (φ, ψ) palauttaa funktion r funktioon s. (Nykyään tämän esimerkkipalautuksen merkitys on vähentynyt, mutta aikanaan se oli tärkeä koska eksponentti- ja logaritmifunktiot saatiin taulukosta ja yhteenlasku kynällä ja paperilla on helpompaa kuin kertolasku.) 114
.. V s Y Funktion r: U X φ ψ palautus funktioon s: V Y käyttäen funktioita. U r X. φ: U V ja ψ: Y X. Esimerkissä siis U = V = R 2, X = Y = R, r(a, b) = ab, s(x, y) = x + y, φ(a, b) = (ln a, ln b) ja ψ(z) = exp(z). 115
Olkoot nyt A Σ ja B Γ päätösongelmia. Funktio f: Σ Γ on rekursiivinen palautus kielestä A kieleen B (eli kielen A rekursiivinen palautus kieleen B) jos f on rekursiivinen ja kaikilla x Σ pätee x A jos ja vain jos f(x) B. Tällöin merkitään f: A m B. Olkoon id joukon { 0, 1 } identiteettikuvaus. Edellä esitettyjä käsitteitä käyttäen f: A m B siis tarkoittaa, että pari (f, id) palauttaa ongelman A karakteristisen funktion π A ongelman B karakteristiseen funktioon π B, eli ja lisäksi f on rekursiivinen. π A (x) = π B (f(x)) kaikilla x Σ, 116
B A fa A fa B Σ Γ Periaatekuva palautuksesta f: A m B (Tässä A = Σ A.) 117
Kieli A palautuu rekursiivisesti kieleen B jos on olemassa rekursiivinen palautus kielestä A kieleen B. Tällöin merkitään A m B. Lause 2.11: [HMU Thm 9.7] Olkoon A m B ja B rekursiivinen (rekursiivisesti lueteltava). Tällöin A on rekursiivinen (vast. rekursiivisesti lueteltava). Todistus: Helppo. Huomaa, että m -palautus on vain eräs erikoistapaus palautuksesta. On olemassa tilanteita, joissa ongelma A kyllä intuitiivisesti voidaan ratkaista ongelman B avulla, mutta ei päde A m B. Esimerkki: yleensä ei päde A m A, missä A = Σ A. Tälläisten tilanteiden tarkastelemiseen tarvitaan jotain voimakkaampaa (ja hankalammin määriteltävää) palautuksen käsitettä, kuten Turing-palautus T. Tällä kurssilla sivuutamme ongelman. 118
Epätyhjyysongelma [HMU 9.3.2] Esimerkkinä palautustekniikasta, ja johdatuksena yleisempään Ricen lauseeseen, tarkastellaan kieltä L ne = { w { 0, 1 } L(M w ) }. Ongelmana on siis päättää annetusta Turingin koneesta, hyväksyykö se ylipäänsä mitään merkkijonoja. Lause 2.12: [HMU Thm. 9.8, 9.9] Kieli L ne on rekursiivisesti lueteltava mutta ei rekursiivinen. Todistus Kiinnostavampi puoli väitteestä on ei-rekursiivisuus, mutta tarkastetaan kuitenkin ensin rekursiivinen lueteltavuus. Tämä käy helpoimmin konstruoimalla epädeterministinen Turingin kone M jolle L ne = L(M). 119
Koneen M laskenta etenee seuraavasti: 1. Kirjoita nauhalle syötteen w jatkoksi 111 ja epädeterministisesti generoitu mielivaltainen x { 0, 1 }. 2. Palaa nauhan alkuun ja simuloi universaalikonetta U syötteellä w111x. Nyt w L ne x L(M w ) jollain x { 0, 1 } w111x L(U) jollain x { 0, 1 } w L(M). /2 120
Ei-rekursiivisuus osoitetaan palautuksella universaalikielestä L u. Siis muodostetaan funktio f jolle f(z) L ne jos ja vain jos z L u, ja lisäksi funktio f on rekursiivinen. Tällöin f: L u m L ne, joten jos L ne olisi rekursiivinen niin myös L u olisi; ristiriita. Funktion f pitää siis annetulla syötteellä z = w111x muodostaa Turingin kone M (tai oikeastaan sen koodi) siten, että jos x L(M w ) niin M ei hyväksy yhtään merkkijonoa jos x L(M w ) niin M hyväksyy ainakin jonkin merkkijonon Konstruktiossa itse asiassa käy jopa niin, että jos x L(M w ) niin M hyväksyy kaikki merkkijonot 121
Tarkastellaan jotain kiinteää z = w111x. Syötteellä y kone M toimii seuraavasti: 1. Pyyhi syöte y pois nauhalta; nauha on nyt tyhjä. 2. Kopioi nauhalle merkkijono x; palauta nauhapää alkuun. 3. Simuloi konetta M w. Konstruktion perusteella on ilmeistä että jos w111x L u niin L(M) = Σ jos w111x L u niin L(M) = Siis jos on olemassa rekursiivinen funktio joka syötteellä z tuottaa koodin v siten, että kone M v toimii kuten M yllä, todistus on valmis. 122
Tarkastellaan nyt tarkemmin, millaisia tiloja ja siirtymiä ylläkuvatussa koneessa M = M v pitäisi olla. Olkoon z = w111x missä x = x 1... x n. pohjana toimii kone M w lisätään alkutilaksi uusi tila ˆq 0, jossa kone kirjoittaa nauhalle tyhjää niin kauan kuin ei-tyhjämerkkejä riittää. Kun tulee vastaan tyhjä, siirrytään uuteen tilaan ˆq 1. lisätään tilat ˆq i, i = 1,..., n, missä tilassa ˆq i, 1 i n 1, kone kirjoittaa merkin x i, siirtyy tilaan ˆq i+1 ja siirtää nauhapäätä oikealla. tilasta ˆq n siirrytään uuteen tilaan ˆq n+1 jossa kone siirtää nauhapäätä takaisin vasemmalle kunnes taas löytyy tyhjämerkki tilasta ˆq n+1 siirrytään alkuperäisen koneen M w alkutilaan siirtymät koneen M w alkuperäisten tilojen välillä säilyvät ennallaan, samoin lopputilat 123
Selvästi yllä kuvattu M = M v toimii kuten väitetään: jos x L(M w ) niin se hyväksyy kaikki syötteet y, muuten ei hyväksy mitään. Kuvaus f, missä f(w111x) = v edellä kuvattuun tapaan, on selvästi rekursiivinen. Siis f on rekursiivinen palautus L u m L ne. Koska L u ei ole rekursiivinen, niin kieli L ne ei sekään ole rekursiivinen. 124
Lause 2.13: [HMU Thm. 9.10] Tyhjyysongelma ei ole osittain ratkeava; ts. kieli ei ole rekursiivisesti lueteltava. L e = { w { 0, 1 } L(M w ) = } Todistus: Aiemmin esitetyn mukaan jos A ja A ovat rekursiivisesti lueteltavia, niin A on rekursiivinen. Koska L e = L ne ja L ne juuri todistettiin ei-rekursiiviseksi mutta rekursiivisesti lueteltavaksi, L e ei voi olla rekursiivisesti lueteltava. Esimerkkinä yksinkertaisesta palautuksesta tarkastellaan kysymystä, onko kahden rekursiivisesti lueteltavan kielen leikkaus tyhjä. Lause 2.14: Kieli L ep = { v111w v, w { 0, 1 }, L(M v ) L(M w ) = } ei ole rekursiivisesti lueteltava. 125
Tekninen huomio: syntaksintarkistus Kielen L ep kiinnostavia tapauksia ovat tietysti sellaiset merkkijonot z = v111w, missä sekä v että w ovat valideja koodeja (eli M v M triv ja M w M triv ). Koska validi koodi alkaa ja loppuu nollalla eikä sisällä merkkijonoa 111, niin merkkijonolla z tällaisessa tapauksessa ei voi olla mitään vaihtoehtoista tulkintaa z = v 111w, missä v v tai w w. Jos merkkijono z on syntaktisesti virheellinen eli ei muotoa v111w tällaisilla v, w, kysymys päteekö z L ep ei vaikuta edes hyvin määritellyltä. Voi nimittäin olla z = v111w = v 111w, missä v v ja w w. Tällöin kuitenkin sekä parista (v, w) että parista (v, w ) ainakin toinen osapuoli sisältää merkkijonon 111, tai alku- tai loppuykkösen, eikä siis ole validi koodi. Sopimuksen mukaan ei-validille koodille x pätee L(M x ) =, joten tässä tapauksessa L(M v ) L(M w ) = L(M v ) L(M w ) = ja z L ep pätee tulkinnasta riippumatta. Siis syntaksivirheelliset syötteet tulevat tässä mukaan kieleen L ep (kunhan niissä on ainakin yksi 111). 126
Lauseen 2.14 todistus: Palautus kielestä L e. Siis muodostetaan rekursiivinen funktio f: { 0, 1 } { 0, 1 }, jolle pätee f(v) L ep v L e. Olkoon w all jokin sellainen koodi, että L(M wall ) = { 0, 1 }. Palautusfunktio f määritellään f(v) = v111w all. Nyt jos v on validi koodi, pätee L(M v ) = L(M v ) { 0, 1 } = L(M v ) L(M wall ) ja siis v L e L(M v ) = L(M v ) L(M wall ) = f(v) L ep. Jos taas v ei ole validi koodi, niin edellä esitetyn huomautuksen mukaan v L e ja f(v) L ep. 127
Siis joka tapauksessa v L e jos ja vain jos f(v) L ep. Funktio f voidaan helposti laskea Turingin koneella: 1. Siirrä nauhapää syötemerkkijonon loppuun. 2. Kirjoita nauhalle merkkijono 111w all. Siis on muodostettu rekursiivinen palautus f: L e m L ep. Jos L ep olisi rekursiivisesti lueteltava, myös L e olisi; ristiriita. 128
Semanttisten ongelmien ratkeamattomuus [HMU 9.3.3] Intuitiivisesti semanttinen ongelma on Turingin konetta koskeva kysymys, jonka vastaus riippuu vain koneen hyväksymästä kielestä. Siis jos L(M) = L(M ), vastauksen on oltava sama koneille M ja M. Muodollisemmin semanttinen ominaisuus S on kokoelma rekursiivisesti lueteltavia aakkoston { 0, 1 } kieliä. Toisin sanoen S RE, missä siis RE = { L(M) { 0, 1 } M Turingin kone syöteaakkostolla { 0, 1 } } Ominaisuus S on ratkeava jos joukko on rekursiivinen. L S = { w { 0, 1 } n L(M w ) S } Esimerkki 2.15: Valitaan S = { }, siis pelkän tyhjän kielen sisältävä luokka. Nyt L S = L e, edellä esitetty tyhjyysongelma, joten S ei ole ratkeava. 129
Semanttinen ominaisuus S on triviaali jos joko S = tai S = RE. Siis ominaisuus on ei-triviaali jos on olemassa kaksi kieltä L, L RE joille L S ja L S. Lause 2.16 (Rice): [HMU Thm. 9.11] Kaikki ei-triviaalit semanttiset ominaisuudet ovat ratkeamattomia. Siis esim. seuraavat ongelmat ovat ratkeamattomia: hyväksyykö M tasan k merkkijonoa (millä tahansa k) hyväksyykö M äärettömän monta merkkijonoa onko koneen M hyväksymä kieli säännöllinen onko koneen M hyväksymä kieli kontekstiton (kaikissa ongelmissa siis syötteenä koneen M koodi) 130
Ricen lauseen todistus: Olkoon S ei-triviaali. Jatkossa esitetään todistus tapaukselle S. Jos S, voidaan samaa todistusta soveltaa ominaisuuteen S = RE S joka on ei-triviaali eikä sisällä kieltä. Todistus perustuu palautukseen universaalikielestä L u. Siis muodostetaan rekursiivinen f: { 0, 1 } { 0, 1 } jolle f(v) L S jos ja vain jos v L u. Toisin sanoen on oltava L(M f(v) ) S jos ja vain jos v = w111x missä x L(M w ). Kun v ei ole muotoa v = w111x millekään koodille w, määritellään f(v) = w 0 missä w 0 on jokin kiinteä koodi jolle L(M w0 ) S. Tarkastellaan nyt miten f(v) määritellään kun v = w111x missä w on validi koodi jollekin koneelle M. 131
Nyt on siis annettuna M = M w ja x, ja pitää konstruoida M = M v jolle L(M ) S jos ja vain jos x L(M). (Ja sitten asetetaan f(w111x) = v.) Olkoon M L jokin kiinteä kone jolle L(M L ) S. Kone M konstruoidaan parin (M, x) perusteella siten, että jos x L(M) niin L(M ) = L(M L ) jos x L(M) niin L(M ) = mikä toteuttaa vaatimukset. 132
Kone M on kaksinauhainen ja toimii syötteellä z seuraavasti: 1. Kopio merkkijono x kakkosnauhalle. 2. Kakkosnauhaa käyttäen simuloi koneen M laskenta syötteellä x 3. Jos simulointi johti hylkäämiseen, hylkää z. (Tässä vaiheessa syötettä z ei ole vilkaistukaan!) 4. Jos simulointi johti hyväksymiseen, simuloi koneen M L laskentaa varsinaisella syötteellä z; hyväksy jos M L hyväksyy. Nyt L(M ) = L(M L ) jos x L(M); muuten L(M ) =. Selvästi merkkijonosta v = w111x missä w on koneen M indeksi voidaan laskea f(v) joka on kuvatun koneen M indeksi. Huomaa että x tulee koodatuksi koneen M sisään eikä ole sen syöte. 133
z M L x M Koneen M konstruktio Ricen lauseessa 134