Пример #1
0
 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)
Пример #2
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
Пример #3
0
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)
Пример #4
0
 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)
Пример #5
0
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
Пример #6
0
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!"
Пример #7
0
 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)
Пример #8
0
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
Пример #9
0
    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
Пример #12
0
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')
Пример #13
0
 def test_write(self):
     t = Tape()
     self.assertEqual(t.read(), 0)
     t.write(1)
     self.assertEqual(t.read(), 1)