Created
April 7, 2016 20:28
-
-
Save RIscRIpt/b7e6fb3080b43e80809680900746a058 to your computer and use it in GitHub Desktop.
Turing machine written in PY3, which converts unary number to binary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import numpy as np | |
from collections import deque | |
clear = lambda: os.system('cls' if os.name=='nt' else 'clear') | |
class TuringTape: | |
def __init__(self, initial_data, empty_symbol): | |
self.data = deque(initial_data) | |
self.base_offset = 0 | |
self.empty_symbol = empty_symbol | |
def __str__(self): | |
return '[' + ']['.join(self.data) + ']' | |
def safe_index(self, index): | |
index += self.base_offset | |
if index >= len(self.data): | |
count = index - len(self.data) + 1 | |
if count > 0: | |
self.expand_right(count) | |
elif index < 0: | |
positions = -index | |
self.shift_right(positions) | |
self.base_offset += positions | |
index = 0 | |
return index | |
def expand_right(self, count): | |
while count > 0: | |
self.data.append(self.empty_symbol) | |
count -= 1 | |
def shift_right(self, positions): | |
while positions > 0: | |
self.data.appendleft(self.empty_symbol) | |
positions -= 1 | |
def shrink(self): | |
while self.data[+0] == self.empty_symbol: | |
self.data.popleft() | |
while self.data[-1] == self.empty_symbol: | |
self.data.pop() | |
def Get(self, index): | |
return self.data[self.safe_index(index)] | |
def Set(self, index, symbol): | |
index = self.safe_index(index) | |
self.data[index] = symbol | |
if symbol == self.empty_symbol: | |
self.shrink() | |
class TuringCommand: | |
def __init__(self, next_state, output, movement): | |
self.next_state = next_state | |
self.output = output | |
self.movement = movement | |
def __str__(self): | |
if self.movement == +1: | |
movement = '>' | |
elif self.movement == -1: | |
movement = '<' | |
else: | |
movement = '|' | |
return '{}:{{{}}}:{}'.format(self.next_state, self.output, movement) | |
class TuringMachine: | |
def __init__(self, tape, tape_head, init_state, end_state, command_table): | |
self.iteration = 0 | |
self.tape = tape | |
self.tape_head = tape_head | |
self.state = init_state | |
self.end_state = end_state | |
self.command_table = command_table | |
self.completed_commands = [] | |
@property | |
def Finished(self): | |
return self.state == self.end_state | |
def Tick(self): | |
if self.Finished: | |
return | |
self.iteration += 1 | |
# Getting current command, according to | |
# current symbol and current state | |
symbol = self.tape.Get(self.tape_head) | |
try: | |
command = self.command_table[self.state][symbol] | |
except KeyError as e: | |
raise Exception("No command defined for the state `{}` and symbol `{}`".format(self.state, symbol)) | |
# Perform the command | |
self.tape.Set(self.tape_head, command.output) | |
self.state = command.next_state | |
self.tape_head += command.movement | |
# Post-command actions | |
self.tape.Get(self.tape_head) # make sure the cell exists | |
self.completed_commands.append(command) | |
def Display(self): | |
print("Iteration:", self.iteration) | |
print(self.tape) | |
print(' ' * ((self.tape_head + self.tape.base_offset) * 3), '^') | |
#print(', '.join(map(str, self.completed_commands))) | |
def main(): | |
MOVE_LEFT = -1 | |
MOVE_RIGHT = +1 | |
MOVE_NONE = 0 | |
tape = TuringTape(list("=||||||||||||"), ' ') | |
cmd_table = { | |
0: { #Initial state | |
'=': TuringCommand(next_state=9, output=' ', movement=MOVE_LEFT), | |
'|': TuringCommand(next_state=1, output=' ', movement=MOVE_LEFT), | |
}, | |
1: { #Moving left to the binary number, and increasing it | |
'|': TuringCommand(next_state=1, output='|', movement=MOVE_LEFT), | |
'=': TuringCommand(next_state=1, output='=', movement=MOVE_LEFT), | |
'1': TuringCommand(next_state=1, output='0', movement=MOVE_LEFT), | |
'0': TuringCommand(next_state=3, output='1', movement=MOVE_RIGHT), | |
' ': TuringCommand(next_state=3, output='1', movement=MOVE_RIGHT), | |
}, | |
3: { #Moving back right to the beginning | |
'0': TuringCommand(next_state=3, output='0', movement=MOVE_RIGHT), | |
'1': TuringCommand(next_state=3, output='1', movement=MOVE_RIGHT), | |
'|': TuringCommand(next_state=3, output='|', movement=MOVE_RIGHT), | |
'=': TuringCommand(next_state=3, output='=', movement=MOVE_RIGHT), | |
' ': TuringCommand(next_state=0, output=' ', movement=MOVE_LEFT), | |
}, | |
} | |
machine = TuringMachine(tape, tape_head=len(tape.data)-1, init_state=0, end_state=9, command_table=cmd_table) | |
while not machine.Finished: | |
machine.Tick() | |
machine.Display() | |
print("=" * 80) | |
input() | |
#clear() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment