def test_get_contents_and_index_shift(self): t = Tape() t.write(1) t.shift_left() tape_contents, index = t.get_contents_and_index() self.assertEqual(tape_contents, [0,1]) self.assertEqual(index, 0)
class TuringMachine(object): def __init__(self, machine_description_file): with open(machine_description_file) as input_file: init_string = input_file.read() split = init_string.split("111") machine_info = split[0] transitions = split[1] inputtape = split[2] split_machine = machine_info.split("1") print("**************Universal Turing Machine**************") print("\nUsing the following metadata:") print(machine_info) print("\nUsing the following transitions:") print(transitions) if len(split_machine) != 7: raise ValueError('Incorrect number of metadata fields') self.states = split_machine[0] self.tape_symbols = split_machine[1] self.input_symbols = split_machine[2] self.blank_symbol = split_machine[3] self.current_state = split_machine[4] self.accept_state = split_machine[5] self.reject_state = split_machine[6] self.transition_table = TransitionTable() print("\nTransition table: ") print("st1\tsym1\tst2\tsym2\tdir") if transitions: split_transitions = transitions.split("11") for transition in split_transitions: self.transition_table.add_transition( Transition.create_from_string(transition)) self.tape = Tape(inputtape.split("1"), self.blank_symbol) def run(self): count = 0 while self.current_state != self.accept_state: if self.current_state == self.reject_state: print("\nTotal head moves: {}".format(count)) print("Rejected") break count += 1 current_symbol = self.tape.read() # print("state: {}, symbol: {}".format(self.current_state, current_symbol)) transition = self.transition_table.get_transition( self.current_state, current_symbol) self.tape.write(transition.next_symbol) if transition.tape_motion == Direction.RIGHT: self.tape.move_right() elif transition.tape_motion == Direction.LEFT: self.tape.move_left() self.current_state = transition.next_state if self.current_state == self.accept_state: print("\nTotal head moves: {}".format(count)) print("Accepted") return self.tape
class Machine(object): def __init__(self, data=None, tape_view=None, cells=[None], position=1): self.tape = Tape(cells, position) self.states = {} self.state = u'0' self.view = tape_view assert data is not None, \ "Action table data argument cannot be None" assert self.view is not None, \ "Tape view argument cannot be None" assert position >= 1 and position <= len(cells), \ "Position must be an existing cell position" for row in data: state = row[0] symbol = row[1] state_new = row[2] symbol_new = row[3] action = row[4] if self.states.get(state): self.states[state].update({ symbol: (state_new, symbol_new, action) }) else: self.states[state] = { symbol: (state_new, symbol_new, action) } def run(self, step_delay=1): self.view.update(self.tape.display_string(), self.tape.position, self.state) time.sleep(step_delay) while self.state != u'h': transition = self.states.get(self.state).get(self.tape.get_symbol()) if transition != None: self.state = transition[0] self.tape.write(transition[1]) if transition[2] == u'>': self.tape.right() elif transition[2] == u'<': self.tape.left() self.view.update(self.tape.display_string(), self.tape.position, self.state) time.sleep(step_delay)
def test_write_shift(self): t = Tape() t.write(1) t.shift_left() self.assertEqual(t.read(), 0) t.shift_right() self.assertEqual(t.read(), 1) t.shift_right() self.assertEqual(t.read(), 0) t.write(2) t.shift_right() t.shift_left() self.assertEqual(t.read(), 2) t.shift_left() self.assertEqual(t.read(), 1)
class System(object): def __init__(self, machine, tape=None): """ Requires a machine instance, and defaults to the default tape is not supllied with one. """ self.machine = machine if tape is None: self.tape = Tape() else: self.tape = tape self.steps = 0 def next(self): """ Allows the machine to proceed one step forward """ self.steps += 1 write_symbol, shift_right = self.machine.next(self.tape.read()) self.tape.write(write_symbol) if shift_right: self.tape.shift_right() else: self.tape.shift_left() def iterate_until_halt(self, max_steps=None): """ Iterates the machine until it halts. If max_step is supplied and reached before a halt occurs, DidNotHalt exception is raised. """ while True: try: self.next() except Halt: return self.steps if max_steps is not None and self.steps >= max_steps: raise DidNotHalt() def get_state_tape_contents_and_head_index(self): tape_contents, head_index = self.tape.get_contents_and_index() return self.machine.state, tape_contents, head_index
def main(): (options, args) = parse_args() cardsFilePath = args[0] tape = Tape(options.defaultValue, options.tapeSize) maxIterations = options.maxIterations with open(cardsFilePath, "r") as handle: cards = json.load(handle) currentState = "start" iterationCount = 0 while (currentState != "halt") and (iterationCount < maxIterations): instructions = cards[currentState][tape.read()] tape.write(instructions["write"]) tape.move(instructions["move"]) currentState = instructions["next"] print currentState print tape.statusToString() iterationCount += 1 if currentState != "halt": print "maximum iterations exceeded!"
def test_get_contents_and_index_write_shfit(self): t = Tape() t.write(1) t.shift_left() t.write(2) t.shift_left() t.shift_right() t.shift_right() t.shift_right() t.shift_right() t.write(3) t.shift_right() t.shift_left() t.shift_left() tape_contents, index = t.get_contents_and_index() self.assertEqual(tape_contents, [2,1,0,3]) self.assertEqual(index, 2)
class TuringMachine(object): """ TuringMachine(machine_config, tape_content) machine_config is a list of attributes of the Turing machine that must be like following: position 0: List of the input alphabet position 1: List of the tape alphabet position 2: Symbol that represents the blank space position 3: List of the states position 4: The initial state position 5: List of the final states position 6: Number of tapes (This Turing machine simulator currently accepts only single-tape machines) position 7 to forward: Transactions in a list format that must be like: position 0: Currently state position 1: Next state position 2: The symbol of tape in current position position 3: The New symbol of tape in current position position 4: The indication of movement (R to right, L to left and S to stay) tape_content is a String that represents the content on the tape at begin of Turing machine computing """ def __init__(self, machine_config, tape_content): self.input_alphabet = machine_config[0] self.tape_alphabet = machine_config[1] self.blank_symbol = ''.join(machine_config[2]) self.states = machine_config[3] self.init_state = ''.join(machine_config[4]) self.final_states = machine_config[5] self.qnt_tapes = int(''.join(machine_config[6])) self.transictions = machine_config[7:] self.tape_content = tape_content self.tape = Tape(self.tape_content, self.blank_symbol) def initialize_computing(self): """ initialize_computing() Initializes the Turing machine computing """ self.print_information() current_state = self.init_state queue = [self.tape] while queue: if current_state in self.final_states: print(self.tape.tape_content) print('Accept') exit(0) valid_transitions = self.valid_transitions(current_state) for transition in valid_transitions: current_state = self.aply_transaction(transition) def validate_input(self): """ validate_input() Input format validation returns 0 if the input format is valid or one of the following for invalid: 1 if has no one input alphabet detected 2 if has no one tape alphabet detected 3 if has no one blank symbol detected 4 if has no one states detected 5 if has no one init state detected 6 if has no one final state detected 7 if the quantity of tapes is different of 1 8 if has no one transition detected """ if self.input_alphabet == ['']: return 1 if self.tape_alphabet == ['']: return 2 if self.blank_symbol == '': return 3 if self.states == ['']: return 4 if self.init_state == '': return 5 if self.final_states == ['']: return 6 if self.qnt_tapes != 1: return 7 if self.transictions == []: return 8 for character in list(self.tape_content) if self.transictions == []: return return 0 def print_information(self): print('Input alphabet: ', self.input_alphabet) print('Tape alphabet: ', self.tape_alphabet) print('Blank symbol: ', self.blank_symbol) print('States: ', self.states) print('Initial state: ', self.init_state) print('Final states: ', self.final_states) print('Quantity of tapes', self.qnt_tapes) def aply_transaction(self, transition): self.tape.write(transition[3]) self.tape.move(transition[4]) return transition[1] def valid_transitions(self, state): valid_transitions = [] for transiction in self.transictions: if transiction[0] == state: if self.tape.read() == transiction[2]: valid_transitions.append(transiction) return valid_transitions
class Machine(): def __init__(self,blankchar="b"): """ @purpose Initialise the Machine class used to keep track of states. The tape starts off with a blank cell. :param blankchar: The blank character representation to use. """ self.states = {} self.transitions = {} self.starting = None self.tape = Tape(blankchar) self.halting_states = {} self.blankchar = blankchar self.current_step = 0 self.current_state = self.starting self.current_read = None self.current_transition = None self.halted = False def get_num_states(self): # Returns the number of states currently in the machine return len(self.states) def is_halted(self): """ @purpose Returns halted in boolean """ return self.halted def halt(self): """ @purpose Sets halt to True """ self.halted = True def set_tape(self, tape): """ @purpose Sets the tape to the initial tape :param tape: Takes in the initial tape :return: """ self.tape.init_tape(tape) def set_blank_char(self, char): """ @purpose Sets the blankchar to char :param char: Takes in character 'b' :return: """ self.blankchar = char def get_tape(self): """ @purpose Returns the whole tape """ return self.tape.print_tape() def get_current_tape_head_pos(self): """ @purpose Returns the current tape head position """ return self.tape.get_head_pos() def set_starting(self, id): """ @purpose Set the current state to the staring state :param id: ID of the state :return: """ try: self.starting = self.states[id] if self.current_step == 0: self.current_state = self.starting except KeyError: raise Exception("State does not exist.") def get_starting_state(self): """ @purpose Returns the starting state """ return self.starting def add_state(self, id, reference): """ @purpose Prints the states image """ try: print self.states[id] raise Exception("State already exists.") except KeyError: self.states[id] = reference print self.states def get_state(self, id): """ @purpose Returns the state with the ID :param id: ID of the state """ return self.states[id] def delete_state(self, id): """ @purpose Deletes the state that was selected :param id: ID of the state that was clicked on :return: """ del self.states[id] def get_num_states(self): """ @purpose Returns the number of states """ return len(self.states) def add_transition(self, origin, destination): #TODO: Transitions not needed for A3 pass def delete_transition(self, origin, destination): #TODO: Transitions not needed for A3 pass def modify_state(self,original_id,new_id): pass def reset_execution(self): # Resets the execution state of the turing machine self.current_step = 0 self.current_read = None self.current_state = self.starting self.current_transition = None self.halted = False def execute(self): """ @purpose When the "Execute" button is clicked, this will execute the Turing Machine by one step """ if self.current_transition is not None: self.current_transition.execute_unhighlight() self.increment_step() self.current_read = self.tape.read() transitions = self.current_state.get_transition_seen(self.current_read) #print self.current_read print transitions if len(transitions) > 0: tran = random.choice(transitions) #for tran in transitions: self.current_transition = tran self.current_transition.execute_highlight() self.current_state = tran.get_end() self.write_current_pos(tran.get_write()) move = tran.get_move() print tran.id, self.current_state.id if move == "L": self.move_left() elif move == "R": self.move_right() elif move == "N": pass print(self.tape.head_pos, self.tape.tape) if len(transitions) == 0: # if no transition if defined for a particular symbol in a state, halts self.halt() def move_left(self): """ @purpose Moves the machine head to the left, and extends the tape if necessary """ self.tape.move_left() def move_right(self): """ @purpose Moves the machine head to the right, and extends the tape if necessary """ self.tape.move_right() def increment_step(self): """ @purpose Maintains a counter of steps for a TM simulation """ self.current_step += 1 def write_current_pos(self, value): """ @purpose Allows for writing data on the current position of the head :param value: The value to be written """ return self.tape.write(value) def check_halt_answer(self): """ @purpose Check whether the Turing Machine halts with a "Yes" or a "No". """ print self.current_state.id if self.current_state.is_halt() is True: content= Label(text="Halted with answer YES") print "halted with answer yes" else: content= Label(text="Halted with answer NO") print "halted with answer no" self._popup = Popup(title="Execution Complete", content=content, size_hint=(0.3, 0.3)) self._popup.open()
class TuringMachine: def __init__(self): self.TransitionTable = [] self.tape1 = Tape() self.tape2 = Tape() self.tape3 = Tape() def __str__(self): """Makes the machine pretty to read.""" M = str(self.tape1) + "\n" + str(self.tape2) + "\n" + str(self.tape3) return M def lookup_transition(self, state, in2): """Searches for a transition in the table, can return None.""" for tuple in self.TransitionTable: if (tuple[0] == state and tuple[1] == in2): return tuple return None def set_head_on_transition(self, transition): """Sets the head of the tape on the given transition.""" index = self.TransitionTable.index(transition) index = index * 6 + 1 self.tape1.head = index def add_transition(self, state, in2, out2, mov2, next_state): """Adds a new transition to the machine's transition table.""" new_tuple = (state, in2, out2, mov2, next_state) # We check that the current state has a transition # for the desired inputs, if it does we overwrite it old_tuple = self.lookup_transition(state, in2) if old_tuple: old_tuple = new_tuple else: # If there is no transition for this state and inputs # we simply add it to the machine's transition table self.TransitionTable.append(new_tuple) def print_transition_table(self): """Prints all of the transitions in the Machine.""" for tuple in self.TransitionTable: print tuple def tape_setup(self, word, initial_state): """Prepares the Machine's tapes for execution.""" # Setting up the three tapes, we cheat here and # don't use the tape's movement and writing methods # for simplicity and efficiency. for transition in self.TransitionTable: for char in transition: self.tape1.tape.append(str(char)) self.tape1.tape.append(";") for char in word: self.tape2.tape.append(char) self.tape3.move("R") self.tape3.write(initial_state) def execute(self, word, initial_state, halt_state, verbose = False): """Executes the machine, prints if the word is Accepted or Crashes.""" self.tape_setup(word, initial_state) # Main Universal Turing Machine execution loop # while our tape3 (the state tape) isn't pointing to halt # we keep executing according to our transition table. # Do note that the machine can infinite loop if its # not programmed properly. while self.tape3.read() != halt_state: current_state = self.tape3.read() input2 = self.tape2.read() instruction = self.lookup_transition(current_state, input2) if instruction: output = instruction[2] movement = instruction[3] next_state = instruction[4] else: raise MachineException("CRASH") yield self self.tape2.write(output) self.set_head_on_transition(instruction) self.tape2.move(movement) self.tape3.write(next_state) yield self print "ACCEPT"
class TuringMachine: def __init__(self, nb_of_states=config.NB_OF_STATES, nb_of_symbols=config.NB_OF_SYMBOLS, init_state=0, init_tape_length=config.TOTAL_ENCODING_LENGTH): self.nb_of_states = nb_of_states self.nb_of_symbols = nb_of_symbols self.init_state = init_state self.current_state = init_state self.tape = Tape(nb_of_symbols, init_tape_length) # [old_state][symbon_read] => ( symbol_to_write, movement, new_state ) #self.action_table = [[ ( 0, '', 0 ) ] * nb_of_symbols ] * nb_of_states # Problem = works by reference self.action_table = [] for old_state in range(nb_of_states): self.action_table.append([]) for symbol_read in range(nb_of_symbols): self.action_table[old_state].append((0, '', 0)) def __del__(self): del self.nb_of_states del self.nb_of_symbols del self.init_state del self.current_state del self.action_table del self.tape def next(self): symbol_read = self.tape.read() try: (symbol_to_write, movement, new_state) = self.action_table[self.current_state][symbol_read] except IndexError: print self.current_state, symbol_read self.debugConfiguration() self.debugState() # Write the new symbol self.tape.write(symbol_to_write) # Move the tape cursor if movement == 'l': self.tape.moveLeft() elif movement == 'r': self.tape.moveRight() # Set the new state self.current_state = new_state def reset(self): self.current_state = self.init_state self.tape.reset() def linearize(self): # Used for testing purposes for old_state in range(self.nb_of_states): for symbol_read in range(self.nb_of_symbols): symbol_to_write = (symbol_read + 1) % self.nb_of_symbols movement = 'r' new_state = (old_state + 1) % self.nb_of_states action = (symbol_to_write, movement, new_state) self.action_table[old_state][symbol_read] = action self.tape.linearize() return self def randomize(self): for old_state in range(self.nb_of_states): for symbol_read in range(self.nb_of_symbols): self.randomizeRow(old_state, symbol_read) return self def randomizeRow(self, old_state, symbol_read): action = self.createRandomAction() self.action_table[old_state][symbol_read] = action return action def createRandomAction(self): symbol_to_write = random.randint(0, self.nb_of_symbols - 1) movement = random.choice(['l', 'r']) new_state = random.randint(0, self.nb_of_states - 1) action = (symbol_to_write, movement, new_state) return action def mutate(self): old_state = random.randint(0, self.nb_of_states - 1) symbol_read = random.randint(0, self.nb_of_symbols - 1) old_action = self.action_table[old_state][symbol_read] new_action = self.randomizeRow(old_state, symbol_read) #print "Mutation: ", (old_state, symbol_read), "=>", old_action, " is now ", new_action return self def addState(self): self.nb_of_states += 1 new_state = [] for i in range(self.nb_of_symbols): action = self.createRandomAction() new_state.append(action) self.action_table.append(new_state) return self def removeState(self): # Remove the last one if self.nb_of_states == 1: # Do nothing return self state_to_remove = self.nb_of_states - 1 del self.action_table[state_to_remove] self.nb_of_states -= 1 if self.current_state == state_to_remove: self.current_state -= 1 # Reindex the action table for old_state in range(self.nb_of_states): for symbol_read in range(self.nb_of_symbols): (symbol_to_write, movement, new_state) = self.action_table[old_state][symbol_read] if new_state == state_to_remove: new_state -= 1 self.action_table[old_state][symbol_read] = (symbol_to_write, movement, new_state) return self def mate1(self, turing_machine): if self.nb_of_states != self.nb_of_states: raise ValueError('Mate: different number of states') if self.nb_of_symbols != self.nb_of_symbols: raise ValueError('Mate: different number of symbols') cut_state = random.randint(0, self.nb_of_states - 1) print "Cut state: ", cut_state action_table_1 = self.action_table[: cut_state] + turing_machine.action_table[ cut_state:] action_table_2 = turing_machine.action_table[: cut_state] + self.action_table[ cut_state:] self.action_table = action_table_1 turing_machine.action_table = action_table_2 return self, turing_machine def mate(self, turing_machine): # Copy the largest action table of the two parents if len(self.action_table) > len(turing_machine.action_table): child = copy.deepcopy(self) parent_2 = turing_machine else: child = copy.deepcopy(turing_machine) parent_2 = self for old_state in range(parent_2.nb_of_states): for symbol_read in range(parent_2.nb_of_symbols): if random.random() > config.MATE_PB: new_action = parent_2.action_table[old_state][symbol_read] child.action_table[old_state][symbol_read] = new_action child.reset() return child def debugConfiguration(self): print "Init state: ", self.init_state print "Number of states: ", len(self.action_table) print "Number of symbols: ", len(self.action_table[0]) print "Action table: " for old_state, action_state in enumerate(self.action_table): for symbol_read, action in enumerate(action_state): print(old_state, symbol_read), "=>", action #self.tape.debugConfiguration() def debugState(self): symbol_read = self.tape.read() action = self.action_table[self.current_state][symbol_read] print "Current action:", (self.current_state, symbol_read), "=>", action
import sys from tape import Direction from tape import Tape if __name__ == '__main__': if len(sys.argv) == 1: print('usage: {} <palindrome>'.format(sys.argv[0])) print('where the format of a palindrome is L = { ww^R | w = (0+1)^* }') sys.exit(0) tape = Tape(sys.argv[1]) while True: if tape.read() == '0': tape.write('x') tape.move_head(Direction.RIGHT) if tape.read() in ['0', '1']: tape.move_head(Direction.RIGHT) elif tape.read() in ['d', 'x', 'y']: break while tape.read() in ['0', '1']: tape.move_head(Direction.RIGHT) if tape.read() in ['d', 'x', 'y']: tape.move_head(Direction.LEFT) if tape.read() == '0': tape.write('x')
def test_write(self): t = Tape() self.assertEqual(t.read(), 0) t.write(1) self.assertEqual(t.read(), 1)