Example #1
0
 def test_move_one_rule_no_tape(self):
     tm = TuringMachine("q4 -> q3")
     assert tm.mconf == "q4" # First m-conf in code is first in simulation
     tm.move()
     assert tm.mconf == "q3"
     with raises(TMLocked):
         tm.move()
Example #2
0
 def test_tape_str_assignment(self):
     tm = TuringMachine() # Without rules
     tape = __import__("string").ascii_letters
     tm.tape = tape
     assert tm.tape == dict(enumerate(tape))
     for symbol in tape:
         assert tm.scan() == symbol
         tm.perform("R")
Example #3
0
 def test_scan(self):
     tm = TuringMachine()
     msg = "It's only a test"
     msg_dict = dict(enumerate(msg, -2))
     tm.tape = msg_dict
     pairs = list(msg_dict.items())
     __import__("random").shuffle(pairs)
     for idx, el in pairs:
         tm.index = idx
         assert tm.scan() == el
Example #4
0
 def test_perform_one_task(self, task, index_delta,
                                 tape_list_before, tape_dict_after):
     tm = TuringMachine() # Without rules
     assert tm.index == 0
     assert tm.tape == {}
     tm.tape = tape_list_before
     assert tm.tape == dict(enumerate(tape_list_before))
     tm.perform(task)
     assert tm.index == index_delta
     assert tm.tape == tape_dict_after
Example #5
0
 def test_scan(self):
     tm = TuringMachine()
     msg = "It's only a test"
     msg_dict = dict(enumerate(msg, -2))
     tm.tape = msg_dict
     pairs = list(msg_dict.items())
     __import__("random").shuffle(pairs)
     for idx, el in pairs:
         tm.index = idx
         assert tm.scan() == el
Example #6
0
 def test_perform_one_task(self, task, index_delta, tape_list_before,
                           tape_dict_after):
     tm = TuringMachine()  # Without rules
     assert tm.index == 0
     assert tm.tape == {}
     tm.tape = tape_list_before
     assert tm.tape == dict(enumerate(tape_list_before))
     tm.perform(task)
     assert tm.index == index_delta
     assert tm.tape == tape_dict_after
Example #7
0
 def test_init_empty(self):
     tm = TuringMachine()
     assert tm.index == 0
     assert tm.tape == {}
     assert len(tm) == 0
     assert len(tm.inv_dict) == 0
     assert not hasattr(self, "mconf")
     with raises(TMLocked):
         tm["a", "0"] # Rule querying
     with raises(TMLocked):
         tm.move()
Example #8
0
 def test_init_empty(self):
     tm = TuringMachine()
     assert tm.index == 0
     assert tm.tape == {}
     assert len(tm) == 0
     assert len(tm.inv_dict) == 0
     assert not hasattr(self, "mconf")
     with raises(TMLocked):
         tm["a", "0"]  # Rule querying
     with raises(TMLocked):
         tm.move()
Example #9
0
 def test_tape_list_assignment_with_blank(self, blank_index):
     tm = TuringMachine() # Without rules
     tape = list(__import__("string").ascii_letters)
     tape[blank_index] = "None"
     expected_tape = {k: v for k, v in enumerate(tape)
                           if k != blank_index % len(tape)}
     tm.tape = tape
     assert len(tm.tape) == len(tape) - 1
     assert tm.tape == expected_tape
     for symbol in tape:
         assert tm.scan() == symbol
         tm.perform("R")
Example #10
0
 def test_perform_and_move_unknown_task(self, task):
     tm_perform = TuringMachine() # Without rules
     with raises(ValueError):
         tm_perform.perform(task)
     if task.strip(): # Parsing rule makes sense
         tm_move_parsed = TuringMachine("a None -> {} a".format(task))
         with raises(ValueError):
             tm_move_parsed.move()
     tm_move_setitem = TuringMachine()
     tm_move_setitem.mconf = "a"
     tm_move_setitem["a", "None"] = ([task], "a")
     with raises(ValueError):
         tm_move_setitem.move()
Example #11
0
 def test_move_two_rules_no_tape(self):
     tm = TuringMachine("a -> b\nb None -> R c\n")
     assert tm.mconf == "a"
     tm.move()
     assert tm.mconf == "b"
     assert tm.scan() == "None"
     tm.move()
     assert tm.mconf == "c"
     with raises(TMLocked):
         tm.move()
Example #12
0
 def test_tape_list_and_dict_assignment_without_blank(self, tape_list):
     tape_dict = dict(enumerate(tape_list))
     tm_list = TuringMachine() # Without rules
     tm_dict = TuringMachine()
     assert tm_list.index == tm_dict.index == 0
     assert tm_list.tape == tm_dict.tape == {}
     tm_list.tape = tape_list
     tm_dict.tape = tape_dict
     assert tm_list.index == tm_dict.index == 0
     assert tm_list.tape == tm_dict.tape == tape_dict
     for symbol in tape_list:
         assert tm_list.scan() == tm_dict.scan() == symbol
         tm_list.perform("R")
         tm_dict.perform("R")
Example #13
0
 def test_move_zero_one_zero_one(self):
     tm = TuringMachine(
         "a -> P0 R b\n"
         "b -> P1 R a\n"
     )
     for unused in range(40):
         assert tm.mconf == "a"
         tm.move()
         assert tm.mconf == "b"
         tm.move()
     tape = tm.tape
     assert len(tape) == 80
     for idx in range(80):
         assert tape[idx] == str(idx % 2)
Example #14
0
 def test_move_two_rules_no_tape(self):
     tm = TuringMachine("a -> b\nb None -> R c\n")
     assert tm.mconf == "a"
     tm.move()
     assert tm.mconf == "b"
     assert tm.scan() == "None"
     tm.move()
     assert tm.mconf == "c"
     with raises(TMLocked):
         tm.move()
Example #15
0
 def test_copy(self):
     tm = TuringMachine("q1      -> P0 R q2\n"
                        "q2 None -> P1 R q1")
     tm.tape = "Test"
     tm.perform("R")
     tm.perform("P1")
     tmcp = tm.copy()
     # Rules and inverted rules
     assert list(tmcp.items()) == list(tm.items())
     assert list(tmcp.inv_dict.items()) == list(tm.inv_dict.items())
     # Complete configuration
     assert tmcp.tape == dict(enumerate("T1st")) == tm.tape
     assert tmcp.index == 1 == tm.index
     assert tmcp.mconf == "q1" == tm.mconf
     tm.move()
     assert tmcp.tape != tm.tape
     assert tmcp.index != tm.index
     assert tmcp.mconf != tm.mconf
     assert tm.tape == dict(enumerate("T0st"))
     assert tm.index == 2
     assert tm.mconf == "q2"
Example #16
0
 def test_move_one_rule_no_tape(self):
     tm = TuringMachine("q4 -> q3")
     assert tm.mconf == "q4"  # First m-conf in code is first in simulation
     tm.move()
     assert tm.mconf == "q3"
     with raises(TMLocked):
         tm.move()
Example #17
0
 def test_tape_str_assignment(self):
     tm = TuringMachine()  # Without rules
     tape = __import__("string").ascii_letters
     tm.tape = tape
     assert tm.tape == dict(enumerate(tape))
     for symbol in tape:
         assert tm.scan() == symbol
         tm.perform("R")
Example #18
0
 def test_tape_dict_assignment(self, blank_index, delta):
     tm = TuringMachine()  # Without rules
     tape = list(__import__("string").ascii_letters)
     tape[blank_index] = "None"
     expected_tape = {
         k + delta: v
         for k, v in enumerate(tape) if k != blank_index % len(tape)
     }
     tape_dict = dict(enumerate(tape, delta))
     tm.tape = tape_dict
     assert tm.tape == expected_tape
     assert tm.index == 0
     assert tm.scan() == tape[-delta] if delta <= 0 else "None"
     for task in delta * "R" + -delta * "L":
         tm.perform(task)
     assert tm.index == delta
     for symbol in tape:
         assert tm.scan() == symbol
         tm.perform("R")
Example #19
0
 def test_copy_without_mconf_nor_rules(self):
     tm = TuringMachine()
     tm.tape = dict(enumerate("TestTestTest", -2))
     tm.perform("L")
     tm.perform("P0")
     tmcp = tm.copy()
     # Rules and inverted rules
     assert list(tmcp.items()) == list(tm.items()) == []
     assert list(tmcp.inv_dict.items()) == list(tm.inv_dict.items()) == []
     # Complete configuration
     assert tmcp.tape == dict(enumerate("T0stTestTest", -2)) == tm.tape
     assert tmcp.index == -1 == tm.index
     tmcp.perform("L")
     tmcp.perform("P1")
     assert tmcp.tape != tm.tape
     assert tmcp.index != tm.index
     assert tmcp.tape == dict(enumerate("10stTestTest", -2))
     assert tmcp.index == -2
     assert not hasattr(tm, "mconf")
     assert not hasattr(tmcp, "mconf")
Example #20
0
 def test_tape_dict_assignment(self, blank_index, delta):
     tm = TuringMachine() # Without rules
     tape = list(__import__("string").ascii_letters)
     tape[blank_index] = "None"
     expected_tape = {k + delta: v for k, v in enumerate(tape)
                                   if k != blank_index % len(tape)}
     tape_dict = dict(enumerate(tape, delta))
     tm.tape = tape_dict
     assert tm.tape == expected_tape
     assert tm.index == 0
     assert tm.scan() == tape[-delta] if delta <= 0 else "None"
     for task in delta * "R" + -delta * "L":
         tm.perform(task)
     assert tm.index == delta
     for symbol in tape:
         assert tm.scan() == symbol
         tm.perform("R")
Example #21
0
 def test_move_zero_one_zero_one(self):
     tm = TuringMachine("a -> P0 R b\n" "b -> P1 R a\n")
     for unused in range(40):
         assert tm.mconf == "a"
         tm.move()
         assert tm.mconf == "b"
         tm.move()
     tape = tm.tape
     assert len(tape) == 80
     for idx in range(80):
         assert tape[idx] == str(idx % 2)
Example #22
0
 def test_copy_without_mconf_nor_rules(self):
     tm = TuringMachine()
     tm.tape = dict(enumerate("TestTestTest", -2))
     tm.perform("L")
     tm.perform("P0")
     tmcp = tm.copy()
     # Rules and inverted rules
     assert list(tmcp.items()) == list(tm.items()) == []
     assert list(tmcp.inv_dict.items()) == list(tm.inv_dict.items()) == []
     # Complete configuration
     assert tmcp.tape == dict(enumerate("T0stTestTest", -2)) == tm.tape
     assert tmcp.index == -1 == tm.index
     tmcp.perform("L")
     tmcp.perform("P1")
     assert tmcp.tape != tm.tape
     assert tmcp.index != tm.index
     assert tmcp.tape == dict(enumerate("10stTestTest", -2))
     assert tmcp.index == -2
     assert not hasattr(tm, "mconf")
     assert not hasattr(tmcp, "mconf")
Example #23
0
 def test_tape_list_assignment_with_blank(self, blank_index):
     tm = TuringMachine()  # Without rules
     tape = list(__import__("string").ascii_letters)
     tape[blank_index] = "None"
     expected_tape = {
         k: v
         for k, v in enumerate(tape) if k != blank_index % len(tape)
     }
     tm.tape = tape
     assert len(tm.tape) == len(tape) - 1
     assert tm.tape == expected_tape
     for symbol in tape:
         assert tm.scan() == symbol
         tm.perform("R")
Example #24
0
 def test_copy(self):
     tm = TuringMachine("q1      -> P0 R q2\n" "q2 None -> P1 R q1")
     tm.tape = "Test"
     tm.perform("R")
     tm.perform("P1")
     tmcp = tm.copy()
     # Rules and inverted rules
     assert list(tmcp.items()) == list(tm.items())
     assert list(tmcp.inv_dict.items()) == list(tm.inv_dict.items())
     # Complete configuration
     assert tmcp.tape == dict(enumerate("T1st")) == tm.tape
     assert tmcp.index == 1 == tm.index
     assert tmcp.mconf == "q1" == tm.mconf
     tm.move()
     assert tmcp.tape != tm.tape
     assert tmcp.index != tm.index
     assert tmcp.mconf != tm.mconf
     assert tm.tape == dict(enumerate("T0st"))
     assert tm.index == 2
     assert tm.mconf == "q2"
Example #25
0
    def test_turing_first_example(self):
        tm1 = TuringMachine( # On p. 233 of his article
            "b None -> P0  R c\n"
            "c None ->   R   e\n"
            "e None -> P1  R f\n"
            "f None ->   R   b\n"
        )
        tm2 = TuringMachine( # On p. 234 of his article, the same idea
            "b None ->   P0   b\n"
            "     0 -> R R P1 b\n"
            "     1 -> R R P0 b\n"
        )
        assert tm1.mconf == tm2.mconf == "b"
        assert tm1.index == tm2.index == 0
        tm1.move() # Syncronizing them
        tm2.move()
        for idx in range(50):
            assert tm2.mconf == "b"

            assert tm1.index == 2 * idx + 1
            tm1.move()
            assert tm1.index == 2 * idx + 2
            tm1.move()
            assert tm1.index == 2 * idx + 3

            assert tm2.index == 2 * idx
            tm2.move()
            assert tm2.index == 2 * idx + 2

            assert tm1.tape == tm2.tape

        tape = tm1.tape
        tape_length = abs(max(tm1.tape) - min(tm1.tape))
        assert tape_length == 100
        for idx in range(100):
            if idx % 2 == 0:
                assert tape[idx] == str(idx // 2 % 2)
            else:
                assert idx not in tape # "None"
Example #26
0
    def test_turing_first_example(self):
        tm1 = TuringMachine(  # On p. 233 of his article
            "b None -> P0  R c\n"
            "c None ->   R   e\n"
            "e None -> P1  R f\n"
            "f None ->   R   b\n")
        tm2 = TuringMachine(  # On p. 234 of his article, the same idea
            "b None ->   P0   b\n"
            "     0 -> R R P1 b\n"
            "     1 -> R R P0 b\n")
        assert tm1.mconf == tm2.mconf == "b"
        assert tm1.index == tm2.index == 0
        tm1.move()  # Syncronizing them
        tm2.move()
        for idx in range(50):
            assert tm2.mconf == "b"

            assert tm1.index == 2 * idx + 1
            tm1.move()
            assert tm1.index == 2 * idx + 2
            tm1.move()
            assert tm1.index == 2 * idx + 3

            assert tm2.index == 2 * idx
            tm2.move()
            assert tm2.index == 2 * idx + 2

            assert tm1.tape == tm2.tape

        tape = tm1.tape
        tape_length = abs(max(tm1.tape) - min(tm1.tape))
        assert tape_length == 100
        for idx in range(100):
            if idx % 2 == 0:
                assert tape[idx] == str(idx // 2 % 2)
            else:
                assert idx not in tape  # "None"
Example #27
0
    def test_mod_3_equals_zero(self, binary_number_string):
        code = "\n".join(
            # Starting with an empty tape, adds the digits to the tape
            ["pre-start -> L"] +
            ["             R P{}".format(el) for el in binary_number_string] +
            [
                "             goto-start",

                # Go back with the "cursor" to the first symbol in tape
                "goto-start",
                "  None -> R start",
                "       -> L goto-start",

                # Starts with zero in mind, so modulo is zero
                "start -> mod0",

                # Every digit d appended to x makes the new number y = x * 2 + d,
                # and the same follows in modulo 3
                "mod0",
                "  0    -> R mod0",
                "  1    -> R mod1",
                "  None -> L return_T",
                "mod1",
                "  0    -> R mod2",
                "  1    -> R mod0",
                "  None -> L return_F",
                "mod2",
                "  0    -> R mod1",
                "  1    -> R mod2",
                "  None -> L return_F",

                # Clears the tape and "prints" to it the desired result
                "return_T",
                "  [0 1] -> E L return_T",
                "  None  -> R PT loop",
                "return_F",
                "  [0 1] -> E L return_F",
                "  None  -> R PF loop",

                # Deadlock
                "loop -> loop",
            ])

        number = int(binary_number_string, base=2)
        all_numbers_tape = dict(enumerate(binary_number_string))
        result = "T" if number % 3 == 0 else "F"
        tm = TuringMachine(code)
        print(code)
        assert tm.tape == {}
        assert tm.index == 0
        assert tm.mconf == "pre-start"

        # Puts the digits into the machine
        tm.move()
        assert tm.tape == all_numbers_tape
        assert tm.index == len(binary_number_string) - 1
        assert tm.mconf == "goto-start"

        # Go back to the beginning
        for digit in reversed(binary_number_string):
            assert tm.scan() == digit
            old_idx = tm.index
            tm.move()
            assert tm.tape == all_numbers_tape
            assert tm.index == old_idx - 1
            assert tm.mconf == "goto-start"
        assert tm.scan() == "None"
        assert tm.index == -1
        tm.move()
        assert tm.tape == all_numbers_tape
        assert tm.index == 0
        assert tm.mconf == "start"

        # Initialization
        tm.move()
        assert tm.tape == all_numbers_tape
        assert tm.index == 0
        assert tm.mconf == "mod0"

        # Follow the digits
        mod_value = 0
        for idx, digit in enumerate(binary_number_string, 1):
            assert tm.scan() == digit
            tm.move()
            mod_value = (mod_value * 2 + int(digit, base=2)) % 3
            assert tm.tape == all_numbers_tape
            assert tm.index == idx
            assert tm.mconf == "mod{}".format(mod_value)

        # After last digit
        return_mconf = "return_" + result
        assert tm.scan() == "None"
        tm.move()
        assert tm.tape == all_numbers_tape
        assert tm.index == len(binary_number_string) - 1
        assert tm.mconf == return_mconf

        # Erases digit per digit
        for digit in reversed(binary_number_string):
            assert tm.scan() == digit
            old_idx = tm.index
            tm.move()
            assert tm.tape == {
                k: v
                for k, v in all_numbers_tape.items() if k < old_idx
            }
            assert tm.index == old_idx - 1
            assert tm.mconf == return_mconf

        # Returns!
        assert tm.scan() == "None"
        for unused in range(5):
            tm.move()
            assert tm.tape == {0: result}
            assert tm.index == 0
            assert tm.mconf == "loop"
Example #28
0
 def test_init_no_first_m_configuration(self):
     with raises(TMSyntaxError):
         TuringMachine(" -> q2")
Example #29
0
 def test_tape_list_and_dict_assignment_without_blank(self, tape_list):
     tape_dict = dict(enumerate(tape_list))
     tm_list = TuringMachine()  # Without rules
     tm_dict = TuringMachine()
     assert tm_list.index == tm_dict.index == 0
     assert tm_list.tape == tm_dict.tape == {}
     tm_list.tape = tape_list
     tm_dict.tape = tape_dict
     assert tm_list.index == tm_dict.index == 0
     assert tm_list.tape == tm_dict.tape == tape_dict
     for symbol in tape_list:
         assert tm_list.scan() == tm_dict.scan() == symbol
         tm_list.perform("R")
         tm_dict.perform("R")
Example #30
0
    def test_mod_3_equals_zero(self, binary_number_string):
        code = "\n".join(
             # Starting with an empty tape, adds the digits to the tape
            ["pre-start -> L"] +
            ["             R P{}".format(el) for el in binary_number_string] +
            ["             goto-start",

             # Go back with the "cursor" to the first symbol in tape
             "goto-start",
             "  None -> R start",
             "       -> L goto-start",

             # Starts with zero in mind, so modulo is zero
             "start -> mod0",

             # Every digit d appended to x makes the new number y = x * 2 + d,
             # and the same follows in modulo 3
             "mod0",
             "  0    -> R mod0",
             "  1    -> R mod1",
             "  None -> L return_T",
             "mod1",
             "  0    -> R mod2",
             "  1    -> R mod0",
             "  None -> L return_F",
             "mod2",
             "  0    -> R mod1",
             "  1    -> R mod2",
             "  None -> L return_F",

             # Clears the tape and "prints" to it the desired result
             "return_T",
             "  [0 1] -> E L return_T",
             "  None  -> R PT loop",
             "return_F",
             "  [0 1] -> E L return_F",
             "  None  -> R PF loop",

             # Deadlock
             "loop -> loop",
            ]
        )

        number = int(binary_number_string, base=2)
        all_numbers_tape = dict(enumerate(binary_number_string))
        result = "T" if number % 3 == 0 else "F"
        tm = TuringMachine(code)
        print(code)
        assert tm.tape == {}
        assert tm.index == 0
        assert tm.mconf == "pre-start"

        # Puts the digits into the machine
        tm.move()
        assert tm.tape == all_numbers_tape
        assert tm.index == len(binary_number_string) - 1
        assert tm.mconf == "goto-start"

        # Go back to the beginning
        for digit in reversed(binary_number_string):
            assert tm.scan() == digit
            old_idx = tm.index
            tm.move()
            assert tm.tape == all_numbers_tape
            assert tm.index == old_idx - 1
            assert tm.mconf == "goto-start"
        assert tm.scan() == "None"
        assert tm.index == -1
        tm.move()
        assert tm.tape == all_numbers_tape
        assert tm.index == 0
        assert tm.mconf == "start"

        # Initialization
        tm.move()
        assert tm.tape == all_numbers_tape
        assert tm.index == 0
        assert tm.mconf == "mod0"

        # Follow the digits
        mod_value = 0
        for idx, digit in enumerate(binary_number_string, 1):
            assert tm.scan() == digit
            tm.move()
            mod_value = (mod_value * 2 + int(digit, base=2)) % 3
            assert tm.tape == all_numbers_tape
            assert tm.index == idx
            assert tm.mconf == "mod{}".format(mod_value)

        # After last digit
        return_mconf = "return_" + result
        assert tm.scan() == "None"
        tm.move()
        assert tm.tape == all_numbers_tape
        assert tm.index == len(binary_number_string) - 1
        assert tm.mconf == return_mconf

        # Erases digit per digit
        for digit in reversed(binary_number_string):
            assert tm.scan() == digit
            old_idx = tm.index
            tm.move()
            assert tm.tape == {k: v for k, v in all_numbers_tape.items()
                                    if k < old_idx}
            assert tm.index == old_idx - 1
            assert tm.mconf == return_mconf

        # Returns!
        assert tm.scan() == "None"
        for unused in range(5):
            tm.move()
            assert tm.tape == {0: result}
            assert tm.index == 0
            assert tm.mconf == "loop"
Example #31
0
def ajax_simulate():
    tm = TuringMachine(request.form["machine"])
    for el in range(3000):
        tm.move()
    return jsonify(tm.tape)
Example #32
0
 def test_perform_and_move_unknown_task(self, task):
     tm_perform = TuringMachine()  # Without rules
     with raises(ValueError):
         tm_perform.perform(task)
     if task.strip():  # Parsing rule makes sense
         tm_move_parsed = TuringMachine("a None -> {} a".format(task))
         with raises(ValueError):
             tm_move_parsed.move()
     tm_move_setitem = TuringMachine()
     tm_move_setitem.mconf = "a"
     tm_move_setitem["a", "None"] = ([task], "a")
     with raises(ValueError):
         tm_move_setitem.move()