Top/TuringMachineSimulator.Py

Top | Top | recent changes | Preferences

#!/usr/bin/python

from string import split, join
from sys import argv

class TM:
      blank = "_"
      accept = "accept"
      reject = "reject"
      start = "start"
      left = "L"
      right = "R"

      #### Tape

      class Tape:
            def __init__(self, input):
                  self.head = 0
                  self.contents = [x for x in input]

            def move_left(self):
                  if(self.head > 0): self.head -= 1

            def move_right(self):
                  self.head += 1
                  if (self.head >= len(self.contents)):
                        self.contents.append(TM.blank)

            def read_symbol(self):
                  return self.contents[self.head]

            def write_symbol(self, symbol):
                  self.contents[self.head] = symbol

            def str(self):
                  return join(self.contents, "") + "\n" + (" " * self.head) + "^"

      #### Transition Function

      class TransitionFunction:
            def __init__(self, file):
                  
                  self.table = {}

                  try:  file = open(file, 'r')
                  except IOError:
                        print "Can't open TM defn file", file
                        raise SystemExit
            
                  line_number = 0

                  def check(cond, *msg):
                        if (not cond):
                              print transition_file, ":", line_number, ":", msg
                              raise SystemExit

                  for line in file.readlines():
                        ++line_number

                        parts = split(line, None, 5)

                        if len(parts) == 0: continue
                        check(len(parts) >= 5,
                              "only", len(parts), "words on line")

                        if len(parts) == 5:  parts.append("")

                        (state1, symbol1, state2, symbol2, move, comment) = parts
       
                        check(move == TM.right or move == TM.left,
                               "unknown move:", move)
                        check(not self.table.has_key((state1, symbol1)),
                               "redundant transition:", line)
                        self.table[state1, symbol1] = (state2, symbol2, move, comment)

            def lookup(self, state, symbol):
                  if (self.table.has_key((state, symbol))):
                        return self.table[state, symbol]
                  return (TM.reject, TM.blank, TM.left, "")

      #### Turing Machine

      def __init__(self, transition_file, initial_tape_str):
          
            self.tape = TM.Tape(initial_tape_str)
            self.fn = TM.TransitionFunction(transition_file)
            self.state = TM.start

      def step(self):

            print self.tape.str(), self.state

            symbol = self.tape.read_symbol()

            (self.state, symbol, move, comment) = self.fn.lookup(self.state, symbol)

            self.tape.write_symbol(symbol)

            if (move == TM.left):  self.tape.move_left()

            else: self.tape.move_right()

      def run(self):

            while (1):
                if (self.state == TM.reject): return 0
                if (self.state == TM.accept): return 1
                self.step()
 
if __name__ == "__main__":
        
   usage = "usage: " + argv[0] + " tmfilename initialtapestring"

   if len(argv) != 3:
      print usage
      raise SystemExit
                        
   tm = TM(argv[1], argv[2])

   if (tm.run()):      print "accept"
   else:               print "reject"

Top | Top | recent changes | Preferences
This page is read-only | View other revisions
Last edited October 14, 2004 3:23 pm by Neal Young (diff)
Search: