Turingov stroj in programiranje Barbara Strniša 12. 4. 2010 1 Opis in definicija Definirajmo nekaj oznak: Σ abeceda... končna neprazna množica simbolov (običajno Σ 2) Σ n = {s 1 s 2... s n ; s i Σ, i = 1, 2,..., n}... nizi, besede dolžine n Σ = n=0 Σn Σ 0 = {λ}... prazen niz Σ... jezik nad abecedo Σ Definicija 1 (neformalni opis) Turingov deterministični stroj je preprost model za računanje, ki sestoji iz traka, nadzorne enote in glave. Na traku, ki je v obe smeri neomejen, je zapisana vsebina. Nadzorna enota vsebuje stanja, glava pa ima določen položaj in se pomika levo in desno ter bere in piše podatke po traku. Definicija 2 (formalna definicija Turingovega stroja) Sestavljen je iz (Γ, Σ, b, Q, q 0, q Y,, δ), kjer velja: Γ je končna abeceda (to so znaki, ki se lahko pojavijo na traku) Σ Γ \ {b} (to so znaki, ki so dovoljeni na vhodu) b Γ \ Σ (b blank; oznaka za prazno celico oz. presledek) Q je končna množica stanj q 0, q Y, Q različni : - q 0... začetno stanje - q Y... končno sprejemno stanje -... končno zavrnitveno stanje δ : (Q \ {q Y, }) Γ Q Γ { 1, 0, 1} je prehodna funkcija. Delovanje stroja: Opišemo s pomočjo konfiguracij (stanje nadzorne enote, položaj glave, vsebina traku). Začetna konfiguracija: - začetno stanje nadzorne enote je q 0 - položaj glave je na celici 0 - vsebina je v celicah 0, 1,..., w 1, w Σ (Dogovor: na traku je zapisanih le končno znakov, ki so različni od b.) 1
Korak delovanja: - trenutna konfiguracija stroja je (q, i, w) - glava prebere vsebino celice i in dobi znak s - nadzorna enota pogleda δ(q, s) = (q, s, ), kjer je q novo stanje, s nov znak, pa premik glave - če je q {q Y, }, se stroj ustavi, sicer nadaljuje - glava v celico i zapiše znak s - novo stanje je q in glava se premakne na celico i + - nova dobljena konfiguracija je (q, i +, w ), kjer je w spremenjena i-ta celica. 2 Naloge Naloga 1 (28. 1. 2010, 4. izpit, 3. naloga) Sestavi Turingov stroj nad abecedo Σ = {0, 1, 2}, ki za niz na vhodu preveri, ali je sestavljen samo iz znakov 1 in 2 ter ne vsebuje treh enakih zaporednih znakov. Primer: Nize 1, 22, 211, 121, 22122, 211221121211 mora stroj sprejeti, nize 222, 11022, 121212221 pa zavrniti. Niz ne sme vsebovati ničle ter 111 ali 222. Če karkoli od tega vsebuje, se program konča. Sprehodimo se po nizu od leve proti desni in si zapomnimo, če glava prebere 1, 11, 2 ali 22. Če glava prebere 2 za 1 ali obratno, se vrnemo v začetno stanje. Γ = {0, 1, 2, b}... znaki, ki se lahko pojavijo na traku Σ = {0, 1, 2}... abeceda q 0... začetno stanje q 1... levo od glave je natanko ena 1 q 11... levo od glave sta dve zaporedni enici q 2... levo od glave je natanko ena 2 q 22... levo od glave sta dve zaporedni dvojki stanje \ znak 0 1 2 b q 0 (, 0, 0) (1) (q 1, 1, +1) (6) (q 2, 2, +1) (11) (q Y, b, 0)(16) q 1 (, 0, 0) (2) (q 11, 1, +1) (7) (q 2, 2, +1) (12) (q Y, b, 0) (17) q 11 (, 0, 0) (3) (, 1, 0) (8) (q 2, 2, +1) (13) (q Y, b, 0) (18) q 2 (, 0, 0) (4) (q 1, 1, +1) (9) (q 22, 2, +1)(14) (q Y, b, 0) (19) q 22 (, 0, 0) (5) (q 1, 1, +1) (10) (, 2, 0) (15) (q Y, b, 0) (20) (1) : prvi prebrani znak je 0 = končamo z zavrnitvenim stanjem, ker smo prebrali 0 (2) : levo od glave je 1 in preberemo 0 = končamo z zavrnitvenim stanjem, ker smo prebrali 0 (3) : levo od glave sta dve enici in preberemo 0 = končamo z zavrnitvenim stanjem, ker smo prebrali 0 (4) : levo od glave je 2 in preberemo 0 = končamo z zavrnitvenim stanjem, ker smo prebrali 0 (5) : levo od glave sta dve dvojki in preberemo 0 = končamo z zavrnitvenim stanjem, ker smo prebrali 0 (6) : prvi prebrani znak je 1 = pomaknemo se v stanje q 1 (7) : levo od glave je 1 in preberemo še eno 1 = pomaknemo se v stanje q 11 2
(8) : levo od glave sta dve enici in preberemo še eno 1 = končamo z zavrnitvenim stanjem, ker smo prebrali tri zaporedne enice (9) : levo od glave je 2 in preberemo 1 = pomaknemo se v stanje q 1 (10) : levo od glave sta dve dvojki in preberemo 1 = pomaknemo se v stanje q 1 (11) : prvi prebrani znak je 2 = pomaknemo se v stanje q 2 (12) : levo od glave je 1 in preberemo 2 = pomaknemo se v stanje q 2 (13) : levo od glave sta dve enici in preberemo 2 = pomaknemo se v stanje q 2 (14) : levo od glave je 2 in preberemo še eno 2 = pomaknemo se v stanje q 22 (15) : levo od glave sta dve dvojki in preberemo še eno 2 = končamo z zavrnitvenim stanjem, ker smo prebrali tri zaporedne dvojke (16) : prvi prebrani znak je prazen = končamo s sprejemnim stanjem q Y, saj naloga ne prepoveduje praznega niza (17) : levo od glave je 1 in preberemo prazen znak = končamo s sprejemnim stanjem q Y (18) : levo od glave sta dve enici in preberemo prazen znak = končamo s sprejemnim stanjem q Y (19) : levo od glave je 2 in preberemo prazen znak = končamo s sprejemnim stanjem q Y (20) : levo od glave sta dve dvojki in preberemo prazen znak = končamo s sprejemnim stanjem q Y Naloga 2 (15. 9. 2008, 3. izpit, 2. naloga) Sestavi Turingov stroj nad abecedo Σ = {0, 1}, ki sprejme natanko besede, v katerih se enice pojavljajo v strnjenih podzaporedjih sode dolžine. Npr.: nize 11011, 1111011, 11011000011 bo stroj sprejel, nize 10110, 10010, 1110010 pa bo zavrnil. Niz ne sme vsebovati vsebovati enic, ki so strnjena v podzaporedja lihe dolžine. Pomikamo se od leve proti desni in beremo znake. Zapomnimo si, v kakšnih strnjenih podzaporedjih so zapisane enice, v lihih ali sodih. Če naletimo na podzaporedje enic lihe dolžine in za tem preberemo 0 ali prazen znak, se program konča. Γ = {0, 1, b}... znaki, ki se lahko pojavijo na traku Σ = {0, 1}... abeceda q ok... smo v začetnem stanju ali levo od glave so enice v strnjenem podzaporedju sode dolžine ali znak 0 q 1L... levo od glave so enice v strnjenem podzaporedju lihe dolžine stanje \ znak 0 1 b q ok (q ok, 0, +1) (1) (q 1L, 1, +1) (3) (q Y, b, 0) (5) q 1L (, 0, 0) (2) (q ok, 1, +1) (4) (, b, 0) (6) (1) : preberemo znak 0 = pomaknemo se v stanje q ok (2) : levo od glave je strnjeno podzaporedje enic lihe dolžine in preberemo 0 = končamo z zavrnitvenim stanjem, ker smo prebrali podzaporedje enic lihe dolžine (3) : smo v začetnem stanju ali levo od glave je 0 ali strnjeno zaporednje enic sode dolžine, preberemo 1 = pomaknemo se v stanje q ok (4) : levo od glave je strnjeno podzaporedje enic lihe dolžine in preberemo 1 = pomaknemo se v stanje q ok (5) : smo v začetnem stanju ali levo od glave je 0 ali strnjeno zaporednje enic sode dolžine, preberemo b = končamo s sprejemnim stanjem q Y (6) : levo od glave je strnjeno podzaporedje enic lihe dolžine in preberemo b = končamo z zavrnitvenim stanjem Naloga 3 (25. 8. 2008, 2. izpit, 2. naloga) Sestavi Turingov stroj, ki razpoznava vhod, ki sestoji iz dveh binarnih besed w in w, ločenih s simbolom 2, kjer je beseda w obrat besede w. Za vhod 111020111 je odgovor DA, za 111020011 ali 112111 pa vrne NE. Pomikamo se od leve proti desni in ugotavljamo, ali sta prvi in zadnji znak niza enaka. 3
Prvi prebrani znak pobrišemo in se pomikamo v desno do konca niza (tj. do praznega znaka b), nato en korak v levo (na zadnji znak), da preverimo še zadnji znak niza in ga izbrišemo. Če sta znaka različna, se program konča, sicer pa znak na koncu izbrišemo in se pomikamo v levo, na začetek in postopek ponavljamo dokler ne pridemo do števila 2, kajti to je znak, ki nam loči besedi w in w. Program končamo tudi, če preberemo več kot eno dvojko. Γ = {0, 1, 2, b}... znaki, ki se lahko pojavijo na traku Σ = {0, 1, 2}... abeceda q Z... začetno stanje q 0... najbolj levi znak besede je bil 0 q 1... najbolj levi znak besede je bil 1 q 2... najbolj levi znak besede je bil 2 q 02... najbolj levi znak besede je bil 0 in prehodili smo znak 2 (smo v besedi w ) q 12... najbolj levi znak besede je bil 1 in prehodili smo znak 2 (smo v besedi w ) q 02P... najbolj levi znak besede je bil 0, prehodili smo 2 in prišli do konca niza na prazen zank b, se vrnemo za en korak v levo in preverimo, ali je zadnji znak niza oz. besede w enak začetnemu znaku besede w (torej, ali je enak 0) q 12P... najbolj levi znak besede je bil 1, prehodili smo 2 in prišli do konca niza na prazen zank b, se vrnemo za en korak v levo in preverimo, ali je zadnji znak niza oz. besede w enak začetnemu znaku besede w (torej, ali je enak 1) q V... stanje vračanja na skrajni levi konec niza stanje \ znak 0 1 2 b q Z (q 0, b, +1) (1) (q 1, b, +1) (2) (q 2, b, +1) (3) (, b, 0) (4) q 0 (q 0, 0, +1) (5) (q 0, 1, +1) (6) (q 02, 2, +1) (7) (, b, 0) (8) q 1 (q 1, 0, +1) (9) (q 1, 1, +1) (10) (q 12, 2, +1) (11) (, b, 0) (12) q 2 (, 0, 0) (13) (, 1, 0) (14) (, 2, 0) (15) (q Y, b, 0) (16) q 02 (q 02, 0, +1) (17) (q 02, 1, +1) (18) (, 2, 0) (19) (q 02P, b, 1) (20) q 12 (q 12, 0, +1) (21) (q 12, 1, +1) (22) (, 2, 0) (23) (q 12P, b, 1) (24) q 02P (q V, b, 1) (25) (, 1, 0) (26) (, 2, 0) (27) (, b, 0) (28) q 12P (, 0, 0) (29) (q V, b, 1) (30) (, 2, 0) (31) (, b, 0) (32) q V (q V, 0, 1) (33) (q V, 1, 1) (34) (q V, 2, 1) (35) (q Z, b, +1) (36) (1) : prvi prebrani znak je 0, si ga zapomnimo in ga pobrišemo = pomaknemo se v stanje q 0 (2) : prvi prebrani znak je 1, si ga zapomnimo in ga pobrišemo = pomaknemo se v stanje q 1 (3) : prvi prebrani znak je 2, si ga zapomnimo in ga pobrišemo = pomaknemo se v stanje q 2 (4) : prvi prebrani znak je b= končamo z zavrnitvenim stanjem (5) : najbolj levi znak niza je 0 in preberemo 0 = pomaknemo se v stanje q 0 in se pomikamo v desno (6) : najbolj levi znak niza je 0 in preberemo 1 = pomaknemo se v stanje q 0 in se pomikamo v desno (7) : najbolj levi znak niza je 0 in preberemo 2 = pomaknemo se v stanje q 02 in se pomikamo v desno (8) : najbolj levi znak niza je 0 in preberemo b = končamo z zavrnitvenim stanjem (9) : najbolj levi znak niza je 1 in preberemo 0 = pomaknemo se v stanje q 1 in se pomikamo v desno (10) : najbolj levi znak niza je 1 in preberemo 1 = pomaknemo se v stanje q 1 in se pomikamo v desno (11) : najbolj levi znak niza je 1 in preberemo 2 = pomaknemo se v stanje q 12 in se pomikamo v desno (12) : najbolj levi znak niza je 1 in preberemo b = končamo z zavrnitvenim stanjem (13) : najbolj levi znak niza je 2 in preberemo 0 = desna stran je daljša, končamo z zavrnitvenim stanjem (14) : najbolj levi znak niza je 2 in preberemo 1 = desna stran je daljša, končamo z zavrnitvenim stanjem (15) : najbolj levi znak niza je 2 in preberemo 2 = prebrali smo dve dvojki, končamo z zavrnitvenim stanjem (16) : najbolj levi znak niza je 2 in preberemo b = niz je sestavljen samo iz znaka 2, končamo s sprejemnim stanjem q Y (17) : najbolj levi znak je bil 0, prehodili smo 2 in prebrali 0 = pomaknemo se v stanje q 02 (18) : najbolj levi znak je bil 0, prehodili smo 2 in prebrali 1 = pomaknemo se v stanje q 02 (19) : najbolj levi znak je bil 0, prehodili smo 2 in prebrali 2 = prebrali smo še eno dvojko; končamo z zavrnitvenim stanjem (20) : najbolj levi znak je bil 0, prehodili smo 2 in prebrali b = prišli smo v skrajni desni konec niza,pomaknemo se za ena v levo in preverimo, če je zadnji znak enak prvemu, torej gremo v stanje q 02P 4
(21) : najbolj levi znak je bil 1, prehodili smo 2 in prebrali 0 = pomaknemo se v stanje q 12 (22) : najbolj levi znak je bil 1, prehodili smo 2 in prebrali 1 = pomaknemo se v stanje q 12 (23) : najbolj levi znak je bil 1, prehodili smo 2 in prebrali 2 = prebrali smo še eno dvojko; končamo z zavrnitvenim stanjem (24) : najbolj levi znak je bil 1, prehodili smo 2 in prebrali b = prišli smo v skrajni desni konec niza,pomaknemo se za ena v levo in preverimo, če je zadnji znak enak prvemu, torej gremo v stanje q 12P (25) : najbolj levi znak je bil 0, prehodili smo 2 in prišli na zadnji znak niza (tj. 0)= znaka se ujemata, začnemo postopek vračanja na začetek, torej se pomaknemo v stanje q V (26) : najbolj levi znak je bil 0, prehodili smo 2 in prišli na zadnji znak niza (tj. 1)= znaka sta različna; končamo z zavrnitvenim stanjem (27) : najbolj levi znak je bil 0, prehodili smo 2 in prišli na zadnji znak niza (tj. 2)= leva stran je daljša; končamo z zavrnitvenim stanjem (28) : najbolj levi znak je bil 0, prehodili smo 2 in prebrali b = torej najbolj desni znak je bil b, končamo z zavrnitvenim stanjem (29) : najbolj levi znak je bil 1, prehodili smo 2 in prišli na zadnji znak niza (tj. 0)= znaka sta različna; končamo z zavrnitvenim stanjem (30) : najbolj levi znak je bil 1, prehodili smo 2 in prišli na zadnji znak niza (tj. 1)= znaka se ujemata, začnemo postopek vračanja na začetek, torej se pomaknemo v stanje q V (31) : najbolj levi znak je bil 1, prehodili smo 2 in prišli na zadnji znak niza (tj. 2)= leva stran je daljša; končamo z zavrnitvenim stanjem (32) : najbolj levi znak je bil 1, prehodili smo 2 in prebrali b = torej najbolj desni znak je bil b, končamo z zavrnitvenim stanjem (33) : vračanje na začetek niza, beremo znake (34) : vračanje na začetek niza, beremo znake (35) : vračanje na začetek niza, beremo znake (36) : vračanje na začetek niza, beremo znake, preberemo znak b = pomaknemo se v začetno stanje q Z in postopek ponavljamo KOMENTAR: Nalogo lahko rešimo tudi na drugačen način. In sicer, sedanji abecedi Σ dodamo dodaten znak, npr. 3 in namesto brisanja znaka, znak prepišemo z znakom 3. Torej, na začetku preberemo prvi znak, si ga zapomnimo in na njegovo mesto zapišemo 3. Sprehodimo se do zadnjega znaka in ga primerjamo s prvim. Če sta znaka različna, se program konča, sicer pa na mesto zadnjega znaka zapišemo znak 3 in postopek ponavljamo. Naloga 4 (5. 6. 2006, 2. kolokcij in 1. izpit, 5. naloga) Sestavi Turingov stroj nad abecedo Σ = {0, 1}, ki prepozna besede, pri katerih je ničel strogo manj kot enic. (Kot delna rešitev šteje, če za abecedo uporabiš še dodaten znak (recimo 2).) Npr.: nize 1111, 1111011, 1101100011 bo stroj sprejel, nize 10010, 000, 0010 pa bo zavrnil. Sprehajamo se iz leve proti desni, si zapomnimo prvi znak niza in ga izbrišemo. Sprehodimo se do skrajnega desnega konca in pogledamo zadnji znak niza: - če sta prvi in zadnji znak različna, ga pobrišemo in se pomikamo v levo, da pridemo na začetek in postopek ponavljamo, - sicer zadnji znak še vedno pobrišemo in se pomikamo v levo ter iščemo različen znak. Če ga najdemo, na njegovo mesto zapišemo začetni prebrani znak in postopek začnemo od začetka. Če različnega znaka ne najdemo, pridemo do praznega znaka in imamo niz samih ničel ali samih enic. V primeru niza samih enic se program konča s sprejemnim stanjem, v primeru niza ničel pa z zavrnitvenim stanjem. Γ = {0, 1, b}... znaki, ki se lahko pojavijo na traku Σ = {0, 1}... abeceda q Z... začetno stanje q 0D... najbolj levi znak niza je 0 in se pomikamo v desno q 1D... najbolj levi znak niza je 1 in se pomikamo v desno q 0L... najbolj levi znak niza je 0, premikamo se v levo in iščemo znak 1 q 1L... najbolj levi znak niza je 1, premikamo se v levo in iščemo znak 0 5
q levo... našli smo različen znak, pomikamo se v levo na začetek niza q 0B... najbolj levi znak niza je 0, nahajamo se na zadnjem znaku in ga pobrišemo q 1B... najbolj levi znak niza je 1, nahajamo se na zadnjem znaku in ga pobrišemo stanje \ znak 0 1 b q Z (q 0D, b, +1) (1) (q D1, b, +1) (2) (, b, 0) (3) q 0D (q 0D, 0, +1) (4) (q 0D, 1, +1) (5) (q 0B, b, 1) (6) q 1D (q 1D, 0, +1) (7) (q 1D, 1, +1) (8) (q 1B, b, 1) (9) q 0L (q 0L, 0, 1) (10) (q levo, 0, 1) (11) (, b, 0)(12) q 1L (q levo, 1, 1) (13) (q 1L, 1, 1) (14) (q Y, b, 0) (15) q levo (q levo, 0, 1) (16) (q levo, 1, 1) (17) (q Z, b, +1) (18) q 0B (q 0L, b, 1) (19) (q levo, b, 1) (20) (, b, 0) (21) q 1B (q levo, b, 1) (22) (q 1L, b, 1) (23) (q Y, b, 0) (24) (1) : prvi prebrani znak je 0 = ga pobrišemo in se pomaknemo v stanje q 0D (2) : prvi prebrani znak je 1 = ga pobrišemo in se pomaknemo v stanje q 1D (3) : prvi prebrani znak je b = končamo z zavrnitvenim stanjem (4) : prvi prebrani znak je 0 in preberemo 0 = pomaknemo se v stanje q 0D (5) : prvi prebrani znak je 0 in preberemo 1 = pomaknemo se v stanje q 0D (6) : prvi prebrani znak je 0 in preberemo b = prišli smo na desni konec, na zadnji znak niza, pomaknemo se v stanje q 0B (7) : prvi prebrani znak je 1 in preberemo 0 = pomaknemo se v stanje q 1D (8) : prvi prebrani znak je 1 in preberemo 1 = pomaknemo se v stanje q 1D (9) : prvi prebrani znak je 1 in preberemo b = prišli smo na desni konec, na zadnji znak niza, pomaknemo se v stanje q 1B (10) : najbolj levi znak je 0, prišli smo do konca niza in sedaj v levo iščemo 1, preberemo 0 = pomaknemo se v stanje q 0L in se pomikamo v levo (11) : najbolj levi znak je 0, prišli smo do konca niza in sedaj v levo iščemo 1, preberemo 1 = ta znak zamenjamo z 0 (tako v bistvu uničimo par različnih znakov) in se pomaknemo v stanje q levo (12) : najbolj levi znak je 0, prišli smo do konca niza in sedaj v levo iščemo 1, preberemo b = prišli smo na začetek in končamo z zavrnitvenim stanjem, ker je v nizu več ničel kot enic (13) : najbolj levi znak je 1, prišli smo do konca niza in sedaj v levo iščemo 0, preberemo 0 = ta znak zamenjamo z 1 (tako v bistvu uničimo par različnih znakov) in se pomaknemo v stanje q levo (14) : najbolj levi znak je 1, prišli smo do konca niza in sedaj v levo iščemo 0, preberemo 1 = pomaknemo se v stanje q 1L (15) : najbolj levi znak je 1, prišli smo do konca niza in sedaj v levo iščemo 0, preberemo b = prišli smo na začetek in končamo s sprejemnim stanjem q Y, ker je v nizu več enic kot ničel (16) : našli smo različen znak in se pomikamo v levo do začetka, preberemo 0 = pomaknemo se v stanje q levo (17) : našli smo različen znak in se pomikamo v levo do začetka, preberemo 1 = pomaknemo se v stanje q levo (18) : našli smo različen znak in se pomikamo v levo do začetka, preberemo b = prišli smo v skrajni levi konec, do začetka in začnemo znova, torej se pomaknemo v stanje q Z (19) : prvi znak niza je 0, nahajamo se na zadnjem znaku niza (skrajno desno), preberemo 0 = nismo našli različnega znaka; znak pobrišemo in se vračamo v levo, se pomaknemo v stanje q 0L (20) : prvi znak niza je 0, nahajamo se na zadnjem znaku niza (skrajno desno), preberemo 1 = našli smo različen znak; znak pobrišemo in se vračamo v levo na začetek, se pomaknemo v stanje q levo (21) : prvi znak niza je 0, nahajamo se na zadnjem znaku niza (skrajno desno), preberemo b = niz ima več ničel kot enic, zato končamo z zavrnitvenim stanjem (22) : prvi znak niza je 1, nahajamo se na zadnjem znaku niza (skrajno desno), preberemo 0 = našli smo različen znak; znak pobrišemo in se vračamo v levo na začetek, se pomaknemo v stanje q levo (23) : prvi znak niza je 1, nahajamo se na zadnjem znaku niza (skrajno desno), preberemo 1 = nismo našli različnega znaka; znak pobrišemo in se vračamo v levo, se pomaknemo v stanje q 1L (24) : prvi znak niza je 1, nahajamo se na zadnjem znaku niza (skrajno desno), preberemo b = niz ima več enic kot ničel, zato končamo s sprejemnim stanjem q Y 6