En större tillämpning: tolk för Turingmaskiner

Slides:



Advertisements
Liknande presentationer
BAS-M Hur du på ett enkelt sätt administrerar din båtklubbs register.
Advertisements

PowerPoint av Bendik S. Søvegjarto Koncept, text och regler av Skage Hansen.
Talföljder formler och summor
PowerPoint av Bendik S. Søvegjarto Koncept, text och regler av Skage Hansen.
Formulär Tänkte nu gå igenom vad ett formulär är och hur man kan skapa dem i Access.
X-mas algebra Är du redo? Klicka!!.
Grunder i PowerPoint 2000 Skapa en ny presentation Rita egna objekt
PowerPoint av Bendik S. Søvegjarto Koncept, text och regler av Skage Hansen.
PowerPoint av Bendik S. Søvegjarto Koncept, text och regler av Skage Hansen.
Array Skriv ett program som frågar följande: ”Hur många tal vill du mata in?” användaren matat in ett tal t.ex n. då frågar programmet n ggr följande.
void hittaMax(int tal[], int antal, int *pmax) { int i; ??=tal[0]; for(i=1;i??) ??=tal[i]; } int main() { int v[]={1,2,3,4,2}; int.
Access med Sebastian och Robert
hej och välkomna EKVATIONER Ta reda på det okända talet.
1 Listor En sekvens värden av samma typ Nr 5. 2 Listor Sekvens av värden, element Variabelt antal Alla med samma typ Bara första elementet direkt åtkomligt.
1 Logikprogrammering ons 11/9 David Hjelm. 2 Repetition Listor är sammansatta termer. De består av en ordnad mängd element. Elementen i en lista kan vara.
2D1311 Programmeringsteknik med PBL
Prolog, Mån 16/9 Rebecca Jonson.
Sökning och sortering Linda Mannila
Funktionen SA10-Grupper. Följande typer av grupper finns: - Grupp i kurs hör alltid ihop med en kurskod - Grupp i program hör alltid ihop med en programkod.
PowerPoint av Bendik S. Søvegjarto Koncept, text och regler av Skage Hansen.
Logikprogrammering Ons, 25/9
C-programmering ID120V William Sandqvist Länkad lista
Inkapsling.
Programmeringsteknik för K och Media
Programmeringsteknik K och Media
Programmeringsteknik för K och Media
Växjö 21 april -04Språk & logik: Kontextfria grammatiker1 DAB760: Språk och logik 21/4: Kontextfria 10-12grammatiker Leif Grönqvist
Föreläsning 2 Datalogi för E1 2D1343
Föreläsning 5 Python: argument från kommando-tolken
Föreläsning 10 Länkade lista Stack och Kö Att arbeta med listor
Växjö 15 april -04Språk & logik: Reguljära uttryck1 DAB760: Språk och logik 15/4: Finita automater och 13-15reguljära uttryck Leif Grönqvist
i olika programmeringsspråk
Programmering B PHP Lektion 2
Programmering B PHP Lektion 3
Pointers. int a=5; int f(int b) { a--; b++; return b; } int main() { int a=3; printf("%d,",f(a)); printf("%d",a); return 0; }
Föreläsning 4 Kö Implementerad med array Implementerad med länkad lista Djup kontra bredd Bredden först mha kö.
Föreläsning 2 Kort Översikt Över Javaspråket. Källkodsformat Unicode används åäöμψζ tillåtna Inte alla miljöer klarar av det Källkod Bytekod Java VM för.
Vektorer (klassen Vector) Sortering
Listor En lista är en föränderlig ordnad samling objekt.
Grundläggande programmering
Algoritmer. Ordet kommer från en persisk författare som kom från al’Khowârizmi (engelskans algorithm). Han skrev boken ’Kitab al jabr w’al-muqabala’.
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 8 ( ) INNEHÅLL:Klasser: -Konstruktorer -Klassvariabler -Instansmetoder -Privata.
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 7 ( ) INNEHÅLL: -Metoder -Lokala variabler -Mera om klasser: -Nyckelorden.
1 Föreläsning 6 Programmeringsteknik och Matlab 2D1312/2D1305 Metoder & parametrar Array API och klassen ArrayList.
Namnrum, räckvidd och rekursion Linda Mannila
F. Drewes, Inst. f. datavetenskap1 Föreläsning 11: Funktionella språk Funktioner och variabler i matematiken Funktionella språk LISP, ML och.
Föreläsning 10 Stränghantering.
Logikprogrammering 21/10 Binära träd
Föreläsning 1 Reserverade ord Javas API Identifierare Litteraler Variabler Kompilering och interpretering.
Föreläsning 5 Arrayer & ArrayList Hur man använder API:n
INTRODUKTION TILL PROGRAMMERING
1 Programmera med strängar nr 9 Tal till sträng Sträng till tal Grep Sträng till lista av ord.
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 2 ( ) INNEHÅLL: -Variabler och datatyper -Tilldelning av variabler -Aritmetiska.
Jonny Karlsson INTRODUKTION TILL PROGRAMMERING Föreläsning 5 ( ) INNEHÅLL: -Metoder.
F4 - Funktioner & parametrar 1 Programmeringsteknik, 4p vt-00 Modularisering ”svarta lådor” Väl definierade arbetsuppgifter Enklare validering Enklare.
William Sandqvist C-programmering ID120V Stack och Kö William Sandqvist
Föreläsning 4 Listor, tupler, och for-loopar. Listor En lista är en föränderlig ordnad samling objekt. Listor skapas med hakparenteser. lista = [12,13,14,15]
1 Mönstermatchning och rekursion Nr 4. 2 Förenklad notation val fnname = fn name => expression Förenklas till fun fnname name = expression Exempel fun.
Karl-Henrik Hagdahl, 11 november Repetition Logikprogrammering: måndag 11 november 2002.
ITM1 Kapitel 8 Datastrukturer Grundläggande datavetenskap, 4p Utgående från boken Computer Science av: J. Glenn Brookshear.
OOP F5:1 Stefan Möller OOP Objekt-orienterad programmering Föreläsning 5 Klasser och objekt Skapa objekt - new Referenser Konstruktorer Inkapsling.
Föreläsning 16 Logik med tillämpningar Innehåll u Information kring kursvärdering och tentagenomgång u Genomgång av övningstenta 2.
F2 1 Programmeringsteknik, 4p vt-00 Kommentarer Allt mellan /* och */ Varje kommentar byts ut mot en blank av kompilatorn /* Exempel på uttryck, tilldelningsoperatorn.
Föreläsning 14 Logik med tillämpningar Innehåll u Cuts och negation u Input/output u Extralogiska predikat u Interaktiva program, failure-drivna.
© Anders Broberg, Lena Kallin Westin, 2007 Datastrukturer och algoritmer Föreläsning 14.
Föreläsning 7 programmeringsteknik och Matlab 2D1312/2D1305 Metoddeklaration och parametrar Arrayer och ArrayList.
Anders Sjögren Data (i primärminnet) som en länkad lista datatypen för varje element i listan är en struktur, post ( struct )
OOP&M - teori1 OOP&M – Föreläsning 5 kap 8-13 Operatorer,typkonvertering, booleska operatorer, if och else.
Växjö 14 april -04Språk & logik: Finita automater1 DAB760: Språk och logik 14/4:Finita automater Leif Grönqvist Växjö Universitet.
KPP053, HT2015 MATLAB, Föreläsning 4
Presentationens avskrift:

En större tillämpning: tolk för Turingmaskiner Haskell En större tillämpning: tolk för Turingmaskiner

Turingmaskiner Du har bekantat dig med Turingmaskiner på Intro till DT/DV, men vi ska repetera lite: En Turingmaskin består av en mängd av oordnade instruktioner av följande struktur: (state, symbol, next symbol, next state, direction) Data består av en sträng som kommer från ett alfabet där ’ ’ alltid ingår. Ett typiskt alfabet är {’ ’, ’0’, ’1’}. Bandet där data finns är oändligt både till vänster och höger (det finns oändligt med blankor till både vänster och höger om datadelen).

Turingmaskiner I början ligger läs- och skrivhuvudet vid första icke-blanka tecknet till vänster. Maskinen befinner sig i tillstånd 1. När en instruktion ska utföras, sker två saker: Man skriver ett nytt tecken på bandet vid skrivhuvudet (det får vara samma tecken som det nuvarande) Läs- och skrivhuvudet rör sig ett steg mot vänster eller höger (L/R) När man väljer nästa instruktion som ska utföras, ser man till Turingmaskinens aktuella tillstånd och det aktuella tecknet. Nu söker man i instruktionsrepertoiren efter en instruktion som motsvarar dessa. Repertoiren måste skrivas så att det finns max. en sådan instruktion. När inget hittas, stannar maskinen.

Turingtolk bottom up I vårt (lite) större exempel ska vi designa och koda en tolk som klarar av att exekvera Turingmaskiner. Vi kommer att definiera problemet bottom up, med olika utmaningar: Modellera data (bandet) Modellera själva Turingmaskinerna (instruktionerna) Definiera de funktioner vi behöver för att skapa ett band och operera på det.

Turingtolk bottom up ... Definiera de funktioner vi behöver för att skapa ett band och operera på det: makeTape moveHead readFromTape writeToTape show (för att se utskriften av ett band) getInstruction (för att söka nästa giltiga instruktion) runTM (för att exekvera en given Turingmaskin)

Turingtolk: modellera bandet Krav: Bandet ska bestå av celler som innehåller antingen en symbol ur det givna alfabetet eller ’ ’. Bandet ska vara oändligt till både vänster och höger. Lösning: Ett band består av en lista av de tecken som kommer före den nuvarande positionen, det tecken som läshuvudet för tillfället befinner sig vid, samt en lista på de tecken som kommer efter den nuvarande positionen.

Turingtolk: modellera bandet Implementation: type Symbol = Char data Tape = Tape [Symbol] Symbol [Symbol] Haskell-nytt: type namnger en datatyp och skapar en typsynonym. data skapar en s k algebraisk datatyp och dess konstruktorer. Stor begynnelsebokstav är ett måste.

Turingtolk: modellera turingmaskinerna Applikationsprogrammen, dvs de egentliga Turingmaskinerna, ska bestå av mängder av instruktionerna med det givna formatet. Implementation: en lista av tupler: data Direction = L | R type State = Integer -- (tillstånd, tecken, nästa tecken, nästa -- tillstånd, riktning) type Instruction = (State, Symbol, Symbol, State, Direction) {- Ändrar ettorna till 0 -} m1 = [ (1, '0', '0', 1, R) , (1, '1', '0', 1, R) ]

Funktionerna: makeTape Ska skapa ett band givet en sträng som ska representera data på bandet. Implementation: {- En hjälpfunktion för att skapa ett band som pekar på det första tecknet i en given sträng. -} mkTape :: String -> Tape mkTape (x:xs) = Tape [] x xs 1 x xs

Funktionerna: makeTape mkTape :: String -> Tape mkTape (x:xs) = Tape [] x xs Ex. *Main> mkTape "11011" [1]1011 Obs! Utskriften produceras av implementationen av Show. 1 x xs

Funktionerna: moveHead Insikt: för att ge illusionen av ett oändligt band sätts automatiskt nya blanktecken till och tas bort om man flyttar läshuvudet utanför den del av bandet som innehåller någon data. OBS! Man tänker här läs- och skrivhuvudet som en lucka där exakt ett tecken syns åt gången. I stället för att föra läs- och skrivhuvudet åt höger, “drar” man bandet ett steg åt VÄNSTER så att ett nytt tecken (dvs nästa tecken åt höger) blir synligt i luckan. 1 1

Funktionerna: moveHead Det finns ett antal olika fall att beakta: Man befinner sig i början av data Man befinner sig i slutet av data man befinner sig i mitten av data Dessa måste hanteras separat för både L och R. 1 1

Funktionerna: moveHead OBS! Eftersom man inte har direkt access via ex. indexering till tecknena på bandet, dvs listelementen, kan de INTE hanteras på samma sätt på den vänstra och den högra bandhalvan, ex. med pekare eller index. Bandet till höger om luckan motsvarar den konceptuella bilden av bandet (tecknen kommer i samma ordning som vi skulle rita dem på papper). Den vänstra bandhalvan ger access till listans första element via cons (:). Det är alltså elementet som står FÖRST i den vänstra listhalvan som tolkas vara tecknet till vänster av skrivhuvudet/luckan osv. 1 Implementation: [ ‘1’, ‘1’, ‘0’, ‘1’] ‘0’ [‘1’, ‘1’, ‘0’]

Funktionerna: moveHead R moveHead :: Direction -> Tape -> Tape Läs- och skrivhuvudet före första tecknet i data: moveHead R (Tape [] ' ' (r:rs)) = Tape [] r rs Implementation: [ ] ‘ ’ [‘1’, ‘1’, ‘0’, ‘1’, ‘1’] [ ] ‘1’ [‘1’, ‘0’, ‘1’, ‘1’] 1 1

Funktionerna: moveHead R moveHead :: Direction -> Tape -> Tape Slutet av data, vid sista tecknet: moveHead R (Tape ls c []) = Tape (c:ls) ' ' [] Implementation: [ ‘1’, ‘0’, ‘1’, ‘1’] ‘ 1’ [ ] – Obs! Spegelbilden! [ ‘1’, ‘1’, ‘0’, ‘1’, ‘1’] ‘ ’ [ ] – Obs! Spegelbilden! 1 1

Funktionerna: moveHead R moveHead :: Direction -> Tape -> Tape Normalfallet, i mitten av data: moveHead R (Tape ls c (r:rs)) = Tape (c:ls) r rs Implementation: [ ‘1’, ‘1’] ‘ 0’ [ ‘1’, ‘1’] – Obs! Spegelbilden! [ ‘0’, ‘1’, ‘1’] ‘1 ’ [‘1’ ] – Obs! Spegelbilden! 1 1

Funktionerna: moveHead L moveHead :: Direction -> Tape -> Tape Vid slutet av data vid första blanktecken: moveHead L (Tape (l:ls) ' ' []) = Tape ls l [] Implementation: [ ‘1’, ‘1’, ‘0’, ‘1’, ‘0’] ‘ ’ [ ] – Obs! Spegelbilden! [ ‘1’, ‘0’, ‘1’, ‘0’] ‘1 ’ [ ] – Obs! Spegelbilden! 1 1

Funktionerna: moveHead L moveHead :: Direction -> Tape -> Tape Vid början av data, vid den första icke-blanka symbolen: moveHead L (Tape [] c rs) = Tape [] ' ' (c:rs) Implementation: [ ] ‘ 0 ’ [‘1’, ‘0’, ‘1’, ‘1’ ] [ ] ‘ ’ [‘0’, ‘1’, ‘0’, ‘1’, ‘1’ ] 1 1

Funktionerna: moveHead L moveHead :: Direction -> Tape -> Tape Normalfallet, vid mitten av data: moveHead L (Tape (l:ls) c rs) = Tape ls l (c:rs) Implementation: [‘1’, ‘0’ ] ‘ 1 ’ [‘0’, ‘1’, ‘1’ ] – Obs! Spegelbild! [‘0’ ] ‘ 1 ’ [‘1’, ‘0’, ‘1’, ‘1’ ] 1 1

Funktionerna: read & write readFromTape :: Tape -> Symbol readFromTape (Tape _ c _) = c *Main> readFromTape (Tape ['1'] '0' ['1', '1']) '0' writeToTape :: Symbol -> Tape -> Tape writeToTape c (Tape ls _ rs) = Tape ls c rs *Main> writeToTape '1' (Tape ['1'] '0' ['1', '1']) 1[1]11 1 1 0 1

Turingtolk: utskrift (Show / show) Visar det resulterade bandet korrekt. Reverserar den vänstra bandhalvan (datadelen) instance Show Tape where show (Tape ls c rs) = (reverse ls) ++ ('[':c:']':rs) *Main> show (mkTape "10101010") "[1]0101010" Haskell-nytt: instance definierar en instans av en klass (polymorfism!). where anger lokala definitioner i en ekvation.

runTM och getInstruction Nu står vi ändligen i beråd att börja använda tolken för att exekvera en Turingmaskin. Detta innebär att vi ska hämta en instruktion och utföra den, hämta nästa instruktion och utföra den osv tills maskinen stannar i brist på en matchande instruktion. runTM är huvudfunktionen, den som kör maskinen. getInstruction hämtar nästa matchande instruktion från instruktionsmängden. För att klara av valet av rätt instruktion används hjälpfunktionen find som importeras från Data.List: find :: (a -> Bool) -> [a] -> Maybe a -- Defined in `Data.List' Väljer första värdet (ifall det finns ett sådant) som uppfyller villkoret ur en lista.

Data.List.find ”The find function takes a predicate and a list and returns the first element in the list matching the predicate, or Nothing if there is no such element. “ http://www.haskell.org/hoogle/?hoogle=Data.List.find find :: (a -> Bool) -> [a] -> Maybe a -- Defined in `Data.List' Haskell-nytt: Maybe används för att signalera att funktionen inte kan producera ett meningsfullt resultat för varje fall. data Maybe a = Nothing | Just a deriving (Eq, Ord, Read, Show)

getInstruction getInstruction hämtar nästa matchande instruktion från instruktionsmängden. getInstruction :: [Instruction] -> (State, Symbol) -> Maybe Instruction getInstruction instrs (state, symbol) = find instrMatcher instrs where instrMatcher (state', symbol', _, _, _) = state == state' && symbol == symbol' -- instrMatcher definieras lokalt i where-satsen så att det blir predikatet som ska tillämpas på listelementen för att se ifall elem. fyller villkoret (i detta fall innebär det att vi söker efter en tupel med ett givet state och en given symbol) -- 'prim' anger state och symbol i listan av instruktioner, dessa jämförs med det state och den symbol vi söker efter.

runTM Vi ska hämta en instruktion och utföra den, hämta nästa instruktion och utföra den osv tills maskinen stannar i brist på en matchande instruktion. runTM är huvudfunktionen, den som kör maskinen. runTM :: [Instruction] -> (Tape, State) -> (Tape, State) runTM instrs (tape, state) = case (getInstruction instrs (state, readFromTape tape)) of Nothing -> (tape, state) -- startläget Just (_, _, symbol', state', dir) -> runTM instrs (moveHead dir (writeToTape symbol' tape), state')

runTM – vad händer här? runTM :: [Instruction] -> (Tape, State) -> (Tape, State) Givet en lista av instruktioner (= en Turingmaskin) och en Tape och ett starttillstånd produceras ett (potentiellt ändrat) Tape och ett sluttillstånd. runTM instrs (tape, state) = case (getInstruction instrs (state, readFromTape tape)) of Först söks den instruktion i mängden som motsvarar (current) state, current symbol (returneras av readFromTape tape) . Alternativ 1 i case är Nothing (ingen instruktion hittas, maskinen stannar); då returnerar vi samma utgångsläge (tape, state): Nothing -> (tape, state) -- startläget

runTM – vad händer här? runTM :: [Instruction] -> (Tape, State) -> (Tape, State) Alternativ 2 i case är Just och ett tupelmönster: Just (_, _, symbol', state', dir) -> De två första elementen spelar ingen roll längre, de behövdes bara för matchningen. Därmot är resten viktiga: symbol’ (next symbol) state’ (next state) dir (nästa steg L/R) ... för det följande, rekursiva anropet: runTM instrs (moveHead dir (writeToTape symbol' tape), state') Producerar en Tape: moveHead :: Direction -> Tape -> Tape Producerar en Tape (med den nya symbolen “i rutan”)

runTM – vad händer här? runTM instrs (moveHead dir (writeToTape symbol' tape), state') writeToTape symbol’ tape ser till att den nya symbolen skrivs på den aktuella cellen (den som är under läs- och skrivhuvudet) moveHead dir xxx (där xxx representerar det ändrade bandet) flyttar nu läs- och skrivhuvudet (rutan) ett steg i den angivna riktningen. runTM instr (yyy, state’) (där yyy representerar bandet efter steget) tar nu hand om det följande rekursiva anropet. runTM :: [Instruction] -> (Tape, State) -> (Tape, State) Producerar en Tape: moveHead :: Direction -> Tape -> Tape yyy xxx Producerar en Tape (med den nya symbolen “i rutan”)

Exempelkörningar: {- Spola till höger, dvs över bandet, utan att ändra något -} m0 = [ (1, '0', '0', 1, R) , (1, '1', '1', 1, R) ] main0 = putStrLn $ show $ runTM m0 (mkTape "111000", 1) *Main> main0 (111000[ ],1) Med applikationsoperatorn $ (alt-4 på Mac) kan du undvika parenteser. Applikationsoperatorn $ är högerassociativ och har prioritet 0.

Exempelkörningar: {- Spola först till höger, dvs över bandet, utan att ändra något, sedan tillbaka -} m00 = [ (1, '0', '0', 1, R) , (1, '1', '1', 1, R) , (1, ' ', ' ', 2, L) -- vänder (tillstånd 2 = åt vänster) , (2, '0', '0', 2, L) , (2, '1', '1', 2, L) , (2, ' ', ' ', 3, R) ] -- sluttillståndet main00 = putStrLn $ show $ runTM m00 (mkTape "111000", 1) *Main> main00 ([1]11000,3)

Exempelkörningar: {- Ändrar ettorna till 0 -} m1 = [ (1, '0', '0', 1, R) , (1, '1', '0', 1, R) ] main1 = putStrLn $ show $ runTM m1 (mkTape "111", 1) *Main> main1 (000[ ],1)

Exempelkörningar: {- Lägger till 001 i slutet av ett binärt tal och spolar tillbaka läshuvudet till startpositionen -} m2 = [ (1, '0', '0', 1, R) , (1, '1', '1', 1, R) , (1, ' ', '0', 2, R) -- slutet: första 0 , (2, ' ', '0', 3, R) -- andra 0 , (3, ' ', '1', 4, L) -- ... och 1. Vänder ... , (4, '0', '0', 4, L) , (4, '1', '1', 4, L) , (4, ' ', ' ', 5, R) ] -- ... och är i början. main2 = putStrLn $ show $ runTM m2 (mkTape "111", 1) *Main> main2 ([1]11001,5)

Exempelkörningar: {- Ser till att antalet 1:or i en binär sträng är delbart med 3. Sätter två bitar till slutet av strängen för detta. -} m3 = [ (1, '0', '0', 1, R) , (1, '1', '1', 3, R) , (2, '0', '0', 2, R) , (2, '1', '1', 1, R) , (3, '0', '0', 3, R) , (3, '1', '1', 2, R) , (1, ' ', '0', 4, R) , (4, ' ', '0', 42, R) , (2, ' ', '1', 4, R) , (5, ' ', '1', 42, R) , (3, ' ', '1', 5, R) ] main3 = putStrLn $ show $ runTM m3 (mkTape "111001", 1) *Main> main3 (11100111[ ],42)

Exempelkörningar: *Main> main4 (111[ ]111,1) {- Producerar en kopia av en binär sträng. Ett ‘ ‘ emellan. -} m4 = [ (1, '0', 'X', 2, R) , (2, '0', '0', 2, R) , (2, '1', '1', 2, R) , (2, ' ', ' ', 3, R) , (3, '0', '0', 3, R) , (3, '1', '1', 3, R) , (3, ' ', '0', 4, L) , (4, '0', '0', 4, L) , (4, '1', '1', 4, L) , (4, ' ', ' ', 4, L) , (4, 'X', '0', 1, R) , (4, 'Y', '1', 1, R) , (1, '1', 'Y', 5, R) , (5, '0', '0', 5, R) , (5, '1', '1', 5, R) , (5, ' ', ' ', 6, R) , (6, '0', '0', 6, R) , (6, '1', '1', 6, R) , (6, ' ', '1', 4, L)] *Main> main4 (111[ ]111,1) *Main> putStrLn $ show $ runTM m4 (mkTape "111001", 1) (111001[ ]111001,1) *Main> putStrLn $ show $ runTM m4 (mkTape "0001000", 1) (0001000[ ]0001000,1) main4 = putStrLn $ show $ runTM m4 (mkTape "111", 1)