Turingmaskinen - en abstrakt datormodell Modeller är viktiga hjälpmedel vid studiet av många fenomen. En bra modell fyller oftast följande krav: Den fångar upp det centrala i sin fysiska motsvarighet Den är (troligen) i mindre skala än sin fysiska motsvarighet Den ignorerar oväsentliga detaljer i sin fysiska motsvarighet Den saknar en del av sin fysiska motsvarighets funktioner En modell av en räkneagent (a computing agent) borde fånga upp följande fyra centrala egenskaper hos sin fysiska motsvarighet: Att ta emot input Att producera output Att lagra i och återvinna information ur minnet Att vidta åtgärder beroende på instruktionerna i algoritmen; dels beroende på vilken input som behandlas, och dels på räkneagentens aktuella tillstånd. Det finns en relativt enkel modell som uppfyller alla dessa krav, den så kallade Turingmaskinen. En Turingmaskin består av ett band uppdelat i celler. I varje cell finns en symbol som måste komma ur ett givet alfabet. En symbol som alltid ingår i alfabetet är blanktecknet ( b ). I varje skede finns det högst ett ändligt antal icke-blanka celler på bandet. En Turingmaskin befinner sig alltid i ett visst tillstånd. Dessa betecknas oftast med siffrorna 1,2,..., k. En Turingmaskin har ett läs/skrivhuvud som alltid befinner sig ovanför någon av cellerna.... b b 0 1 1 b b b b... cs 8/A. Soini 1 1 current state (aktuellt tillstånd)
En Turingmaskin kan utföra bara en (typ av) primitiv operation: Skriv in en ny symbol i cellen (får vara samma symbol som den tidigare) OCH byt tillstånd (kan byta till samma tillstånd) OCH flytta läs/skrivhuvudet ett steg till höger eller vänster. Allt detta sker alltså i den primitiva operationen. Dessa operationer är i hög grad beroende av maskinens nuvarande, aktuella tillstånd och av den symbol som finns i den aktuella cellen. En primitiv operation för en Turingmaskin kan alltså beskrivas av följande femtupel: {current state, current symbol, next symbol, next state, move direction} {current state, current symbol, next symbol, next state, move direction} Dessa måste vara entydiga; för varje kombination av {current state, current symbol} får det finnas högst en operation. De primitiva operationer som vi definierar för en viss Turingmaskin utgör dess program. Vi stipulerar dessutom att maskinen alltid startar i den första icke-blanka cellen på bandet (räknat från vänster), och att den alltid startar i tillstånd 1. Programmet stoppar när det kommer till en sådan kombination av ett tillstånd och en cell att ingen operation är definierad för denna kombination. Med dessa restriktioner blir Turingmaskinen en utmärkt modell för en räkneagent, och därmed för en algoritm. cs 8/A. Soini 2
Turingmaskinen kan enklast beskrivas med hjälp av ett tillståndsdiagram: Ex. Bit-inverterare: varje 0 skall bli en 1, varje 1 skall bli en 0 1 : 1/0/R state 1 0/1/R När man är i tillstånd 1, och ser en 1, så ska man skriva en 0 och gå i tillstånd 1 och ta ett steg till höger (R). När man är i tillstånd 1, och ser en 0, så ska man skriva en 1 och gå i tillstånd 1 och ta ett steg till höger (R). Vilket ger oss följande instruktioner: 1. (1,1,0,1,R) // ändrar 1 till 0 2. (1,0,1,1,R) // ändrar 0 till 1 Programmet stannar när det ser det första blanktecknet; det finns ingen instruktion för kombinationen tillstånd 1, symbol b: (1, b, -, -, -). 1 Obs! Fast vi i exemplen ser mest alfabetet (b, 0, 1) är det ingalunda förbjudet att utöka alfabetet vid behov! cs 8/A. Soini 3
Ex. Unära tal: bara siffran 1 används. Tolkning: decimalt unärt 0 1 1 11 2 111 3 1111...... Uppgiften: inkrementera (med ett) det unära talet på bandet: 1/1/R state 1 state 2 b/1/r (1, 1, 1, 1, R) // går över ettorna (1, b, 1, 2, R) // ersätter första blankan med en 1... b b b 1 1 b// 1 b b b... 1 current state (aktuellt tillstånd) Effektivitet? O(N). Finns det en bättre lösning? 1/1/L state 1 state 2 b/1/l (1, 1, 1, 1, L) // tar ett steg åt vänster (1, b, 1, 2, L) // sätter en 1 i början av strängen cs 8/A. Soini 4
... b b b// 1 1 1 b b b b... Denna lösning har effektiviteten O(1). 1-> 2 current state (aktuellt tillstånd) Ex. Addera paritetsbit (udda paritet). Vi har en sträng bestående av 0:or och 1:or. Antalet 1:or ska bli udda. Så, när strängen tar slut, ska vi skriva paritetsbiten i slutet; 0, om antalet ettor var udda att börja med, annars 1. 1/1/R 0/0/R state 1 state 2 0/0/R b/1/r 1/1/R state 3 b/0/r State 1, som är startläget, representerar jämn paritet (det kan ju hända att vi bara har 0:or). State 2 motsvaras av udda paritet. En 0 i strängen ändrar inte läget. En 1 däremot för oss från jämnt tillstånd till udda tillstånd eller tvärtom. Vi ändrar inte de bitar vi tittar på. Först när strängen tar slut (när vi träffar blanktecknet) är det dags att ersätta det med antingen en 0 eller en 1; 0, om vi kommer dit från det udda läget, 1, om vi kommer dit från det jämna läget. cs 8/A. Soini 5
1. (1, 1, 1, 2, R) // jämn paritet, läser 1, byt läge 2. (1, 0, 0, 1, R) // jämn paritet, läser 0, ingen ändring 3. (2, 1, 1, 1, R) // udda paritet, läser 1, byt läge 4. (2, 0, 0, 2, R) // udda paritet, läser 0, ingen ändring 5. (1, b, 1, 3, R) // strängen slut, jämn paritet, skriv 1 och stanna. 6. (2, b, 0, 3, R) // strängen slut, udda paritet, skriv 0 och stanna. cs 8/A. Soini 6