initial commit
This commit is contained in:
commit
0f15e187e1
1
README.md
Normal file
1
README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
Kommentiertes Beispielprogramm ist in der Datei testProgram.tur
|
125
TuringInterpreter.py
Executable file
125
TuringInterpreter.py
Executable file
@ -0,0 +1,125 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from Turingmachine import *
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def getLinesFromFile(filename):
|
||||||
|
content = []
|
||||||
|
with open(filename, "r") as f:
|
||||||
|
content = f.read().splitlines()
|
||||||
|
|
||||||
|
return content
|
||||||
|
|
||||||
|
def createTuringmachineFromLines(lineArray, userInput):
|
||||||
|
k = None
|
||||||
|
F = None
|
||||||
|
S = None
|
||||||
|
I = None
|
||||||
|
|
||||||
|
inputStr = userInput
|
||||||
|
|
||||||
|
d = []
|
||||||
|
|
||||||
|
lineCounter = 0
|
||||||
|
|
||||||
|
for line in lineArray:
|
||||||
|
lineCounter += 1
|
||||||
|
|
||||||
|
line = line.replace(" ","")
|
||||||
|
|
||||||
|
if len(line) > 0:
|
||||||
|
if line[0] == 'k' and line[-1] == ';':
|
||||||
|
#hole k:
|
||||||
|
l = line[1:-1] #entferne k und ;
|
||||||
|
kStr = l.replace("=","") #entferne whitespaces und =
|
||||||
|
k = int(kStr)
|
||||||
|
|
||||||
|
elif line[0] == 'F' and line[-1] == ';':
|
||||||
|
#hole Endzustände:
|
||||||
|
l = line[1:-1] #entferne F und ;
|
||||||
|
FStr = l.replace("=","") #entferne whitespaces und =
|
||||||
|
F = FStr.split(",")
|
||||||
|
|
||||||
|
elif line[0] == 'S' and line[-1] == ';':
|
||||||
|
#hole Startzustand:
|
||||||
|
l = line[1:-1] #entferne S und ;
|
||||||
|
S = l.replace("=","") #entferne whitespaces und =
|
||||||
|
elif line[0] == 'I' and line[-1] == ';':
|
||||||
|
#hole Input:
|
||||||
|
l = line[1:-1] #entferne S und ;
|
||||||
|
I = l.replace("=","") #entferne whitespaces und =
|
||||||
|
elif line[0] == '$' and line[-1] == ';':
|
||||||
|
#hole Zustandsübergang:
|
||||||
|
l = line[1:-1] #entferne $ und ;
|
||||||
|
tmp = l.replace("=","") #entferne whitespaces und =
|
||||||
|
splittedLine = tmp.split(",")
|
||||||
|
|
||||||
|
#parse orientations:
|
||||||
|
orientations = []
|
||||||
|
for i in range(len(splittedLine[4])):
|
||||||
|
if splittedLine[4][i] == 'l':
|
||||||
|
orientations.append (-1)
|
||||||
|
elif splittedLine[4][i] == 'r':
|
||||||
|
orientations.append (1)
|
||||||
|
elif splittedLine[4][i] == 'n':
|
||||||
|
orientations.append (0)
|
||||||
|
else:
|
||||||
|
print("ERROR in line " + str(lineCounter) + ": " + line)
|
||||||
|
return None
|
||||||
|
d.append((splittedLine[0],splittedLine[1],splittedLine[2],splittedLine[3],orientations))
|
||||||
|
|
||||||
|
elif line[0] == '#':
|
||||||
|
#bei Kommentaren tu nix
|
||||||
|
None
|
||||||
|
else:
|
||||||
|
print("ERROR in line " + str(lineCounter) + ": " + line)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if k is None:
|
||||||
|
print("ERROR: no k defined in Turing Program!")
|
||||||
|
return None
|
||||||
|
if F is None:
|
||||||
|
print("ERROR: no F defined in Turing Program!")
|
||||||
|
return None
|
||||||
|
if S is None:
|
||||||
|
print("ERROR: no S defined in Turing Program!")
|
||||||
|
return None
|
||||||
|
|
||||||
|
if inputStr is None:
|
||||||
|
if I is None:
|
||||||
|
print("WARNING: there is no input string defined. Machine will use an empty input string")
|
||||||
|
inputStr = ""
|
||||||
|
else:
|
||||||
|
inputStr = I
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return Turingmachine(d, S, F, k, inputStr)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
filename = sys.argv[1]
|
||||||
|
except:
|
||||||
|
print("ERROR: no input file. \n"
|
||||||
|
+ "usage: python TuringInterpreter.py [TuringProgramFile] [InputString] [SleepTimePerStep] \n"
|
||||||
|
+ "(Default value for SleepTimePerStep is 0.3)")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
inputStr = sys.argv[2]
|
||||||
|
except:
|
||||||
|
inputStr = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
sleepTime = float(sys.argv[3])
|
||||||
|
except:
|
||||||
|
sleepTime = 0.3
|
||||||
|
|
||||||
|
tm = createTuringmachineFromLines(getLinesFromFile(filename), inputStr)
|
||||||
|
|
||||||
|
if tm is None:
|
||||||
|
print("ERROR: Bad Program!")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
tm.run(sleepTime)
|
||||||
|
|
||||||
|
|
200
Turingmachine.py
Executable file
200
Turingmachine.py
Executable file
@ -0,0 +1,200 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import numpy as np
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
# Bezeichnungen:
|
||||||
|
# delta = Zustandsübergangsfunktion: eine Liste von Tupeln im Format:
|
||||||
|
# (aktuellerZustand, aktuelleZeichen[Tupel], nächsterZustand, zuSchreibendeZeichen[Tupel], orientation[Tupel])
|
||||||
|
# q0 = Startzustand
|
||||||
|
# F = Menge der Endzustände
|
||||||
|
|
||||||
|
#ein paar konstanten:
|
||||||
|
GO_LEFT = -1
|
||||||
|
GO_NOWHERE = 0
|
||||||
|
GO_RIGHT = 1
|
||||||
|
|
||||||
|
#zur vereinfachung: konstanten für indices in delta:
|
||||||
|
DELTA_CURRENT_STATE = 0
|
||||||
|
DELTA_CURRENT_CHARS = 1
|
||||||
|
DELTA_NEXT_STATE = 2
|
||||||
|
DELTA_NEXT_CHARS = 3
|
||||||
|
DELTA_ORIENTATIONS = 4
|
||||||
|
|
||||||
|
#Konstanten für die Ausgabe:
|
||||||
|
CURSOR_UP_ONE = '\x1b[1A'
|
||||||
|
ERASE_LINE = '\x1b[2K'
|
||||||
|
|
||||||
|
#hilfsfunktionen für die ausgabe:
|
||||||
|
def eraseLines(n):
|
||||||
|
for i in range(n):
|
||||||
|
print(CURSOR_UP_ONE + ERASE_LINE, end = "")
|
||||||
|
|
||||||
|
#und die eigentliche Turingmaschine:
|
||||||
|
class Turingmachine(object):
|
||||||
|
def __init__(self,delta, q0, F, n, inputStr):
|
||||||
|
self.delta = delta
|
||||||
|
self.q0 = q0
|
||||||
|
self.F = F
|
||||||
|
|
||||||
|
self.n = n
|
||||||
|
|
||||||
|
#zur internen Verwaltung der Turinmaschine brauchen wir folgendes:
|
||||||
|
self.stripes = []
|
||||||
|
self.positions = []
|
||||||
|
|
||||||
|
self.steps = 0 #counting the steps
|
||||||
|
|
||||||
|
for i in range(n):
|
||||||
|
self.stripes.append(['$'])
|
||||||
|
self.positions.append(0)
|
||||||
|
|
||||||
|
#schreibe unsere Eingabe auf das erste Band:
|
||||||
|
for c in inputStr:
|
||||||
|
self.stripes[0].append(c)
|
||||||
|
|
||||||
|
self.currentQ = q0
|
||||||
|
self.error = False
|
||||||
|
self.isInFinalState = False
|
||||||
|
|
||||||
|
self.firstPrint = True
|
||||||
|
|
||||||
|
# Lese char unter dem i-ten Lesekopf:
|
||||||
|
def readChar(self,i):
|
||||||
|
|
||||||
|
#erweitere Band, falls notwendig:
|
||||||
|
if len(self.stripes[i]) <= self.positions[i]:
|
||||||
|
self.stripes[i].append('_')
|
||||||
|
|
||||||
|
#und Zeichen zurückgeben:
|
||||||
|
return self.stripes[i][self.positions[i]]
|
||||||
|
|
||||||
|
# Schreibe char unter dem i-ten Lesekopf:
|
||||||
|
def writeChar(self,i, char):
|
||||||
|
|
||||||
|
#erweitere Band, falls notwendig:
|
||||||
|
if len(self.stripes[i]) <= self.positions[i]:
|
||||||
|
self.stripes[i].append('_')
|
||||||
|
|
||||||
|
#und setze Zeichen:
|
||||||
|
self.stripes[i][self.positions[i]] = char
|
||||||
|
|
||||||
|
#bewege den Lese-/Schreibkopf
|
||||||
|
def move(self, i, orientation):
|
||||||
|
self.positions[i] += orientation
|
||||||
|
|
||||||
|
#führe einen Zustandsübergang aus: (gibt true bei erfolg zurück, sonst false)
|
||||||
|
def runDelta(self):
|
||||||
|
|
||||||
|
#durchlaufe alle Übergänge in Delta
|
||||||
|
for d in self.delta:
|
||||||
|
|
||||||
|
#suche nach Übergängen für unseren Zustand:
|
||||||
|
if d[DELTA_CURRENT_STATE] == self.currentQ:
|
||||||
|
|
||||||
|
#prüfe Einganszeichen:
|
||||||
|
qInputChars = d[DELTA_CURRENT_CHARS]
|
||||||
|
isInputOK = True
|
||||||
|
for i in range(self.n):
|
||||||
|
if not ((qInputChars[i] == self.readChar(i)) or (qInputChars[i] == '*')):
|
||||||
|
#eingangszeichen stimmen nicht überein!
|
||||||
|
isInputOK = False
|
||||||
|
|
||||||
|
if isInputOK:
|
||||||
|
#jetzt haben wir den richtigen zustandsübergang gefunden!
|
||||||
|
qNextChars = d[DELTA_NEXT_CHARS]
|
||||||
|
qOrientations = d[DELTA_ORIENTATIONS]
|
||||||
|
for i in range(self.n):
|
||||||
|
#schreibe Zeichen:
|
||||||
|
if qNextChars[i] != '*':
|
||||||
|
self.writeChar(i, qNextChars[i])
|
||||||
|
#Bewege Lese-/Schreibkopf
|
||||||
|
self.move(i, qOrientations[i])
|
||||||
|
|
||||||
|
#prüfe auf underflows:
|
||||||
|
for j in range(self.n):
|
||||||
|
if self.positions[j] < 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
#setze nächsten Zustand:
|
||||||
|
self.currentQ = d[DELTA_NEXT_STATE]
|
||||||
|
self.steps+=1
|
||||||
|
|
||||||
|
#fertig!
|
||||||
|
return True
|
||||||
|
|
||||||
|
#wenn wir bis hierhin kommen, haben wir keinen Übergang gefunden!
|
||||||
|
return False
|
||||||
|
|
||||||
|
# mache einen einzelnen Schritt mit der Turing Maschine (gibt true bei erfolg zurück, sonst false)
|
||||||
|
def step(self):
|
||||||
|
#führe den Schritt nuraus, wenn wir noch nicht im Endzustand sind:
|
||||||
|
if not self.isInFinalState:
|
||||||
|
self.error = not self.runDelta()
|
||||||
|
|
||||||
|
#schaue, ob wir in einem Endzustand sind:
|
||||||
|
self.isInFinalState = (self.currentQ in self.F)
|
||||||
|
|
||||||
|
return self.error
|
||||||
|
return True
|
||||||
|
|
||||||
|
def printMachine(self):
|
||||||
|
if not self.firstPrint:
|
||||||
|
#Lösche voherige Ausgabe:
|
||||||
|
eraseLines(2 * self.n + 1)
|
||||||
|
self.firstPrint = False
|
||||||
|
#geben bänder aus:
|
||||||
|
for i in range(self.n):
|
||||||
|
print("[",end="")
|
||||||
|
for c in self.stripes[i]:
|
||||||
|
print(c,end = "")
|
||||||
|
print("]")
|
||||||
|
#drucke lese-/Schreibkopf
|
||||||
|
print (" " * (self.positions[i] +1) + "^")
|
||||||
|
|
||||||
|
#und gebe allgemeine Infos aus:
|
||||||
|
print("step: " + str(self.steps) + "\t currentState: " + str(self.currentQ))
|
||||||
|
|
||||||
|
#run the machine until it gets to a final state:
|
||||||
|
def run(self, delayInSeconds):
|
||||||
|
while not self.isInFinalState:
|
||||||
|
self.step()
|
||||||
|
self.printMachine()
|
||||||
|
if self.error:
|
||||||
|
print("ERROR! Please check your Turing Program") #TODO: aussagekräftigere Fehlermeldung?
|
||||||
|
break
|
||||||
|
time.sleep(delayInSeconds)
|
||||||
|
if not self.error:
|
||||||
|
self.printMachine()
|
||||||
|
print("Maschine terminatet!")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
#Blatt13/Aufgabe01 zum testen:
|
||||||
|
|
||||||
|
F = ['finalState']
|
||||||
|
d = [('start',"$$$$",'init',"$$$$",(1,1,1,1)),
|
||||||
|
('init',"****",'a',"*!!!",(0,1,1,1)),
|
||||||
|
('a',"a***",'a',"aa**",(1,1,0,0)),
|
||||||
|
('a',"b***",'b',"b***",(0,0,0,0)),
|
||||||
|
('b',"b***",'b',"b*b*",(1,0,1,0)),
|
||||||
|
('b',"c***",'c',"c***",(0,0,0,0)),
|
||||||
|
('c',"c***",'c',"c**c",(1,0,0,1)),
|
||||||
|
('c',"_***",'counting',"_***",(-1,-1,-1,-1)),
|
||||||
|
('counting',"*abc",'counting',"*abc",(0,-1,-1,-1)),
|
||||||
|
('counting',"*!**",'checkCounter',"*!**",(0,0,0,0)),
|
||||||
|
('counting',"**!*",'checkCounter',"**!*",(0,0,0,0)),
|
||||||
|
('counting',"***!",'checkCounter',"***!",(0,0,0,0)),
|
||||||
|
('checkCounter','*!!!','wordAccepted','*!!!',(0,0,0,0)),
|
||||||
|
('checkCounter','****','wordNotAccepted','****',(0,0,0,0)),
|
||||||
|
('wordAccepted','$***','write1','$***',(1,0,0,0)),
|
||||||
|
('wordAccepted','****','wordAccepted','_***',(-1,0,0,0)),
|
||||||
|
('wordNotAccepted','$***','write0','$***',(1,0,0,0)),
|
||||||
|
('wordNotAccepted','****','wordNotAccepted','_***',(-1,0,0,0)),
|
||||||
|
('write0','****','finalState','0***',(0,0,0,0)),
|
||||||
|
('write1','****','finalState','1***',(0,0,0,0))
|
||||||
|
]
|
||||||
|
|
||||||
|
tm = Turingmachine(d, 'start', F, 4, "aaaaaaaaabbbbbbbbbccccccccc")
|
||||||
|
|
||||||
|
tm.run(0.15)
|
106
add.tur
Executable file
106
add.tur
Executable file
@ -0,0 +1,106 @@
|
|||||||
|
#!./TuringInterpreter.py
|
||||||
|
#
|
||||||
|
#Ein Turingprogramm, das zwei Binärcodierte zahlen
|
||||||
|
#miteinander addiert
|
||||||
|
|
||||||
|
k = 4;
|
||||||
|
S = start;
|
||||||
|
F = end;
|
||||||
|
I = 101001+110;
|
||||||
|
|
||||||
|
|
||||||
|
#init:
|
||||||
|
$start,$$$$,readFirst,$$$$,rrrr;
|
||||||
|
|
||||||
|
#lese erste Zahl ein und schreibe die auf das 2. Band:
|
||||||
|
$readFirst,1***,readFirst,11**,rrnn;
|
||||||
|
$readFirst,0***,readFirst,00**,rrnn;
|
||||||
|
$readFirst,+***,readSecond,****,rnnn;
|
||||||
|
|
||||||
|
#lese zweite Zahl ein und schreibe die auf das 3. Band:
|
||||||
|
$readSecond,1***,readSecond,1*1*,rnrn;
|
||||||
|
$readSecond,0***,readSecond,0*0*,rnrn;
|
||||||
|
$readSecond,_***,clear,****,nnnn;
|
||||||
|
|
||||||
|
#Lösche das erste band:
|
||||||
|
$clear,$***,add,$***,rlln;
|
||||||
|
$clear,****,clear,_***,lnnn;
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#und addiere. Konkret: laufe auf Band 2 und 3 rückwärts die Zahlen
|
||||||
|
# ab und schreibe das ergebnis in rückwärtiger Schreibweise
|
||||||
|
# auf das dritte Band.
|
||||||
|
# dabei gibt es folgende Möglichkeiten:
|
||||||
|
|
||||||
|
# 1. wir haben bei beiden inputs gerade eine null und keinen Übertrag
|
||||||
|
# vorher gehabt:
|
||||||
|
|
||||||
|
$add,*00_,add,*000,nllr;
|
||||||
|
|
||||||
|
# 2. wir haben bei beiden inputs gerade eine null und haben einen Übertrag:
|
||||||
|
$add,*001,add,*001,nllr;
|
||||||
|
|
||||||
|
# 3. beide inputs verschieden ohne übertrag vorher:
|
||||||
|
|
||||||
|
$add,*10_,add,*101,nllr;
|
||||||
|
$add,*01_,add,*011,nllr;
|
||||||
|
|
||||||
|
# 4. beide inputs verschieden mit übertrag vorher:
|
||||||
|
|
||||||
|
$add,*101,overflow,*100,nllr;
|
||||||
|
$add,*011,overflow,*010,nllr;
|
||||||
|
|
||||||
|
# 5. beide inputs gleich 1 ohne übertrag:
|
||||||
|
|
||||||
|
$add,*11_,overflow,*110,nllr;
|
||||||
|
|
||||||
|
# 6. beide inputs 1 mit übertrag vorher:
|
||||||
|
$add,*111,overflow,*111,nllr;
|
||||||
|
|
||||||
|
# 7. wir sind am ende von einem band (dann juss nur noch der inhalt vom anderen
|
||||||
|
# angehängt werden):
|
||||||
|
$add,*$**,addSecondInput,*$**,nnnn;
|
||||||
|
$add,**$*,addFirstInput,**$*,nnnn;
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# anhängeFunktionen:
|
||||||
|
#sind wir fertig?
|
||||||
|
$addSecondInput,**$*,copyResult,**$*,nnnn;
|
||||||
|
#haben wir overflow?
|
||||||
|
$addSecondInput,**01,addSecondInput,**01,nnlr;
|
||||||
|
$addSecondInput,**11,overflow2,**10,nnlr;
|
||||||
|
#sonst:
|
||||||
|
$addSecondInput,**0_,addSecondInput,**00,nnlr;
|
||||||
|
$addSecondInput,**1_,addSecondInput,**11,nnlr;
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# anhängeFunktionen:
|
||||||
|
#sind wir fertig?
|
||||||
|
$addFirstInput,*$**,copyResult,*$**,nnnn;
|
||||||
|
#haben wir overflow?
|
||||||
|
$addFirstInput,*0*1,addFirstInput,*0*1,nlnr;
|
||||||
|
$addFirstInput,*1*1,overflow1,*1*0,nlnr;
|
||||||
|
#sonst:
|
||||||
|
$addFirstInput,*0*_,addFirstInput,*0*0,nlnr;
|
||||||
|
$addFirstInput,*1*_,addFirstInput,*1*1,nlnr;
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#overflow funktionen:
|
||||||
|
|
||||||
|
$overflow,****,add,***1,nnnn;
|
||||||
|
$overflow1,****,addFirstInput,***1,nnnn;
|
||||||
|
$overflow2,****,addSecondInput,***1,nnnn;
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#und schreibe Ergebnis auf das erste Band:
|
||||||
|
|
||||||
|
$copyResult,***$,end,***$,nnnn;
|
||||||
|
$copyResult,***1,copyResult,1**1,rnnl;
|
||||||
|
$copyResult,***0,copyResult,0**0,rnnl;
|
||||||
|
$copyResult,***_,copyResult,***_,nnnl;
|
||||||
|
|
15
nachfolger.tur
Executable file
15
nachfolger.tur
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#!./TuringInterpreter.py
|
||||||
|
k = 1;
|
||||||
|
S = start;
|
||||||
|
F = end;
|
||||||
|
I = 0100101011;
|
||||||
|
|
||||||
|
$start,$,runToEnd,$,r;
|
||||||
|
|
||||||
|
#laufe ans ende der eingabe:
|
||||||
|
$runToEnd,_,addOne,_,l;
|
||||||
|
$runToEnd,*,runToEnd,*,r;
|
||||||
|
|
||||||
|
#addiere eins:
|
||||||
|
$addOne,0,end,1,l;
|
||||||
|
$addOne,1,addOne,0,l;
|
108
testProgram.tur
Executable file
108
testProgram.tur
Executable file
@ -0,0 +1,108 @@
|
|||||||
|
#!./TuringInterpreter.py
|
||||||
|
#
|
||||||
|
# dies ist ein Beispielprogramm für die Turingmaschine
|
||||||
|
# (Hinweis: Kommentarzeilen können mit einer führenden Raute eingeleitet werden)
|
||||||
|
#
|
||||||
|
# Dieses Programm kann mit dem Python-Skript "TuringInterpreter.py" für einen beliebigen Input-String via
|
||||||
|
#
|
||||||
|
# "python TuringInterpreter.py <TuringProgramFile.tur> <InputString>"
|
||||||
|
#
|
||||||
|
# ausgeführt werden. der InputString wird dabei auf das oberste Band geschrieben
|
||||||
|
#
|
||||||
|
# Folgendes Turingprogramm prüft, ob eine eingabe Element
|
||||||
|
# der Sprache L = {a^n b^n c^n} ist. Es schreibt eine 1
|
||||||
|
# auf das erste Band, falls das Wort akzeptiert wird,
|
||||||
|
# und 0 sonst.
|
||||||
|
|
||||||
|
# definiere die Anzahl der Bänder:
|
||||||
|
|
||||||
|
k = 4;
|
||||||
|
|
||||||
|
# definiere Endzustand. Es können alternativ auch mehrere Enzustände (durch Kommata getrennt)
|
||||||
|
# angegeben werden
|
||||||
|
|
||||||
|
F = finalState;
|
||||||
|
|
||||||
|
# definiere Startzustand
|
||||||
|
|
||||||
|
S = start;
|
||||||
|
|
||||||
|
# definiere einen default input String, der benutzt wird, falls beim Programmaufruf
|
||||||
|
# keiner angegeben wird:
|
||||||
|
|
||||||
|
I = aaaaaabbbbbbcccccc;
|
||||||
|
|
||||||
|
|
||||||
|
# definiere Zustandsübergänge:
|
||||||
|
# Ein Zustandsübergang wird mit einem '$' eingeleitet und besteht durch Kommata getrennt aus folgenden Werten:
|
||||||
|
#
|
||||||
|
# 1. Ausgangszustand
|
||||||
|
#
|
||||||
|
# 2. Zeichen unter den Lese-/Schreibköpfen vor dem Zustandswechsel.
|
||||||
|
# '*' kann hier als Platzhalter genutzt werden, um jedes beliebige Zeichen zu akzeptieren
|
||||||
|
#
|
||||||
|
# 3. Zustand, zu dem gewechselt werden soll
|
||||||
|
#
|
||||||
|
# 4. Zeichen, die auf die Bänder geschrieben werden sollen.
|
||||||
|
# '*' bewirkt hier, dass kein Zeichen geschrieben wird
|
||||||
|
# (oder anders interpretiert: Es wird exakt das Zeichen geschrieben,
|
||||||
|
# das vorher gelesen wurde)
|
||||||
|
#
|
||||||
|
# 5. Anschließende Bewegungen der Lese-/Schreibköpfe. Zu verwenden ist folgende Notation:
|
||||||
|
#
|
||||||
|
# n: keine Bewegung
|
||||||
|
# l: Bewegung um ein Feld nach links
|
||||||
|
# r: Bewegung um ein Feld nach rechts
|
||||||
|
#
|
||||||
|
# Und noch ein Hinweis: die Turingmaschine sucht in der Reihenfolge nach dem richtigen Übergang,
|
||||||
|
# wie sie in der Programmdatei angegeben wurden. Das lässt sich in Verbindung mit Platzhaltern
|
||||||
|
# prima nutzen um if-else verzweigungen zu generieren, ohne dass dabei alle theoretisch denkbaren
|
||||||
|
# Zeichenkombinationen als eigener Zustandsübergang angegeben werden müssen ;)
|
||||||
|
|
||||||
|
|
||||||
|
# am Anfang stehen alle Köpfe auf dem $-Zeichen, dass immer am Anfang jedes Bandes steht, also
|
||||||
|
# bewegen wir alle Köpfe einen Schritt nach rechts:
|
||||||
|
$start, $$$$, init , $$$$, rrrr;
|
||||||
|
|
||||||
|
# die unteren drei köpfe schreiben ein !. (um nachher zu sehen, wo sie starteten):
|
||||||
|
$init,****,a,*!!!,nrrr;
|
||||||
|
|
||||||
|
# lese alle a-s auf dem ersten Band ein: (und schreibe exakt so viele auf das zweite Band):
|
||||||
|
$a , a*** , a , aa** ,rrnn;
|
||||||
|
$a , b*** , b , b*** ,nnnn;
|
||||||
|
$a , **** , badInput, ****, nnnn;
|
||||||
|
|
||||||
|
# verfahre genauso mit b:
|
||||||
|
$b , b*** , b , b*b* ,rnrn;
|
||||||
|
$b , c*** , c , c*** ,nnnn;
|
||||||
|
$b , **** , badInput, ****, nnnn;
|
||||||
|
|
||||||
|
# und mit c:
|
||||||
|
$c , c*** , c , c**c ,rnnr;
|
||||||
|
$c , _*** , counting , _*** ,llll;
|
||||||
|
$c , **** , badInput, ****, nnnn;
|
||||||
|
|
||||||
|
# lasse die unteren drei köpfe zurücklaufen, bis einer auf das ! trifft:
|
||||||
|
$counting , *abc , counting , *abc , nlll;
|
||||||
|
$counting , *!** , checkCounter , *!** , nnnn;
|
||||||
|
$counting , **!* , checkCounter , **!* , nnnn;
|
||||||
|
$counting , ***! , checkCounter , ***! , nnnn;
|
||||||
|
|
||||||
|
# sind alle beim Ausrufezeichen?
|
||||||
|
$checkCounter , *!!! , wordAccepted,*!!!,nnnn;
|
||||||
|
$checkCounter , **** , wordNotAccepted,****,nnnn;
|
||||||
|
|
||||||
|
# falls ja: löschen wir alles auf dem ersten Band und schreiben eine 1
|
||||||
|
$wordAccepted , $*** , write1,$***,rnnn;
|
||||||
|
$wordAccepted , **** , wordAccepted,_***,lnnn;
|
||||||
|
$write1 , **** , finalState , 1*** ,nnnn;
|
||||||
|
|
||||||
|
# falls nein: löschen wir alles auf dem ersten Band und schreiben eine 0
|
||||||
|
$wordNotAccepted , $*** , write0 , $*** ,rnnn;
|
||||||
|
$wordNotAccepted , **** , wordNotAccepted , _*** ,lnnn;
|
||||||
|
$write0 , **** , finalState , 0*** ,nnnn;
|
||||||
|
|
||||||
|
# hilfsfunktion, um das Band auch nach vornehin zu löschen:
|
||||||
|
$badInput, _***, wordNotAccepted, _****, nnnn;
|
||||||
|
$badInput, ****, badInput, _***, rnnn;
|
||||||
|
|
42
testProgramUncommented.tur
Normal file
42
testProgramUncommented.tur
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#!./TuringInterpreter.py
|
||||||
|
#
|
||||||
|
# dies ist ein Beispielprogramm für die Turingmaschine
|
||||||
|
# (Hinweis: Kommentarzeilen können mit einer führenden Raute eingeleitet werden)
|
||||||
|
#
|
||||||
|
# Dieses Programm kann mit dem Python-Skript "TuringInterpreter.py" für einen beliebigen Input-String via
|
||||||
|
#
|
||||||
|
# "python TuringInterpreter.py <TuringProgramFile.tur> <InputString>"
|
||||||
|
#
|
||||||
|
# ausgeführt werden. der InputString wird dabei auf das oberste Band geschrieben
|
||||||
|
#
|
||||||
|
# Folgendes Turingprogramm prüft, ob eine eingabe Element
|
||||||
|
# der Sprache L = {a^n b^n c^n} ist. Es schreibt eine 1
|
||||||
|
# auf das erste Band, falls das Wort akzeptiert wird,
|
||||||
|
# und 0 sonst.
|
||||||
|
|
||||||
|
k = 4;
|
||||||
|
F = finalState;
|
||||||
|
S = start;
|
||||||
|
I = aaaaaabbbbbbcccccc;
|
||||||
|
|
||||||
|
$start, $$$$, init , $$$$, rrrr;
|
||||||
|
$init,****,a,*!!!,nrrr;
|
||||||
|
$a , a*** , a , aa** ,rrnn;
|
||||||
|
$a , b*** , b , b*** ,nnnn;
|
||||||
|
$b , b*** , b , b*b* ,rnrn;
|
||||||
|
$b , c*** , c , c*** ,nnnn;
|
||||||
|
$c , c*** , c , c**c ,rnnr;
|
||||||
|
$c , _*** , counting , _*** ,llll;
|
||||||
|
$counting , *abc , counting , *abc , nlll;
|
||||||
|
$counting , *!** , checkCounter , *!** , nnnn;
|
||||||
|
$counting , **!* , checkCounter , **!* , nnnn;
|
||||||
|
$counting , ***! , checkCounter , ***! , nnnn;
|
||||||
|
$checkCounter , *!!! , wordAccepted,*!!!,nnnn;
|
||||||
|
$checkCounter , **** , wordNotAccepted,****,nnnn;
|
||||||
|
$wordAccepted , $*** , write1,$***,rnnn;
|
||||||
|
$wordAccepted , **** , wordAccepted,_***,lnnn;
|
||||||
|
$write1 , **** , finalState , 1*** ,nnnn;
|
||||||
|
$wordNotAccepted , $*** , write0 , $*** ,rnnn;
|
||||||
|
$wordNotAccepted , **** , wordNotAccepted , _*** ,lnnn;
|
||||||
|
$write0 , **** , finalState , 0*** ,nnnn;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user