Skip to content

Commit

Permalink
Adds Tape class
Browse files Browse the repository at this point in the history
  • Loading branch information
cslarsen committed Mar 7, 2016
1 parent 16c365c commit 17616b9
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__
80 changes: 58 additions & 22 deletions busybeaver.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,55 @@
import collections
import sys

class Tape:
def __init__(self, position=0, default=0):
self.tape = collections.defaultdict(lambda: default)
self._position = position
self.leftmost = 0
self.rightmost = 0

@property
def position(self):
return self._position

@position.setter
def position(self, value):
self._position = value

def _update_extremes(self):
self.leftmost = min(self.leftmost, self._position)
self.rightmost = max(self.rightmost, self._position)

def read(self):
self._update_extremes()
return self.tape[self.position]

def write(self, value):
self._update_extremes()
self.tape[self.position] = value

def left(self):
self.position -= 1

def right(self):
self.position += 1

def values(self):
return self.tape.values()

def __str__(self):
s = ""
for index in range(self.leftmost, 1+self.rightmost):
s += "%s " % self.tape[index]
return s[:-1]

def __repr__(self):
return "<Tape: position=%d leftmost=%d rightmost=%d tape=%s>" % (self.position,
self.leftmost, self.rightmost, repr(dict(self.tape)))


class TuringMachine:
def __init__(self, state=0, position=0, tape=None, transition=None):
def __init__(self, state=0, transition=None):
"""A Universal Turing machine.
Args:
Expand All @@ -18,16 +65,9 @@ def __init__(self, state=0, position=0, tape=None, transition=None):
next state) values.
"""
self.state = state
self.position = position
self.tape = tape
self.tape = Tape()
self.transition = transition

if self.tape is None:
self.tape = collections.defaultdict(lambda: 0)

self.leftmost = 0
self.rightmost = 0

def __repr__(self):
return "Machine(state=%s, position=%s, tape=%s, transition=%s)" % (
self.state, self.position, self.tape, self.transition)
Expand All @@ -39,27 +79,25 @@ def __str__(self):
def step(self):
"""Perform one computation step."""
# Read symbol at current tape position
symbol = self.tape[self.position]
symbol = self.tape.read()

# Look up action based on the current state and the read symbol
write, move, state = self.transition[(self.state, symbol)]
symbol, move, state = self.transition[(self.state, symbol)]

# Perform these actions
self.tape[self.position] = write
self.position += move
self.tape.write(symbol)
self.tape.position += move
self.state = state

if self.position < self.leftmost:
self.leftmost = self.position
if self.position > self.rightmost:
self.rightmost = self.position

def run(self, steps=None):
"""Runs the machine an unlimited or given number of steps.
Args:
steps: If None, run indefinitely. If a positive number, run for
that number of steps.
Raises:
KeyError: The given state was not found. Effectively means to halt.
"""
if steps is None:
while True:
Expand All @@ -78,7 +116,6 @@ def ones(self):
return sum(self.tape.values())



def print_result(machine):
for (state, symbol), instr in sorted(machine.transition.items()):
state = chr(ord("A") + state)
Expand All @@ -90,8 +127,7 @@ def print_result(machine):
if next != "H":
next = chr(ord("A") + next)
print("%s %s: %s%s%s" % (state, symbol, write, move, next))
print("Result: <%d> %s <%s>" % (machine.leftmost, " ".join(map(str,
machine.tape.values())), machine.rightmost))
print("Result: %s --- %s" % (machine.tape, repr(machine.tape)))

def sigma(states):
def instr():
Expand All @@ -116,7 +152,7 @@ def all_transitions():
}
yield trans

best = -1
best = 0
for num, tran in enumerate(all_transitions()):
machine = BusyBeaver(transition=tran)
try:
Expand Down

0 comments on commit 17616b9

Please sign in to comment.