diff --git a/py/input.txt b/py/input.txt new file mode 100644 index 0000000..ee17dcb --- /dev/null +++ b/py/input.txt @@ -0,0 +1,5 @@ +11110111 +q1 1 1 r q1 +q1 0 1 r q1 +q1 _ _ l q2 +q2 1 _ n q0 \ No newline at end of file diff --git a/py/main.py b/py/main.py new file mode 100644 index 0000000..9fc0765 --- /dev/null +++ b/py/main.py @@ -0,0 +1,13 @@ +import sys +from turing_machine import * + +if len(sys.argv) > 1: + input_file = sys.argv[1] +else: + input_file = "input.txt" + +tm = TuringMachine(input_file) +tm.parseFile() +tm.makeTransitionTables() +tm.turingSimulator() + diff --git a/py/turing_machine.py b/py/turing_machine.py new file mode 100644 index 0000000..cfefe4a --- /dev/null +++ b/py/turing_machine.py @@ -0,0 +1,145 @@ +import time + +def init_2d_list(dim1, dim2, val): + return [[val for j in range(dim2)] for i in range(dim1)] + + +def add_to_dict(d, key, val): + if key in d: + return False + else: + d[key] = val + return True + + +class TuringMachine(): + def __init__(self, input_file_name): + self.input_file_name = input_file_name + self.num_states = 0 + self.num_alphs = 0 + self.ptr = 0 + self.accept_state = [] + self.state_id = {} + self.alph_id = {} + self.state_table = [] + self.dir_table = [] + self.write_table = [] + self.tape = "" + + def displayTape(self, present_state_id): + flog = open("log.txt", 'a') + + print('\r', self.tape[0:self.ptr], sep='', end='') + print('[', self.tape[self.ptr], ']', sep='', end='') + print(self.tape[self.ptr+1:], sep='', end='') + + flog.write(self.tape[0:self.ptr]) + flog.write('[' + self.tape[self.ptr] + ']') + flog.write(self.tape[self.ptr+1:]) + + # get name of the present state + state_name = '' + for key, val in self.state_id.items(): + if val == present_state_id: + state_name = key + print(' ', state_name, ' ', sep='', end='') + flog.write(' ' + state_name + '\n') + + time.sleep(0.2) + flog.close() + + def parseFile(self): + fin = open(self.input_file_name, 'r') + self.tape = fin.readline().strip() + for line in fin: + strs = line.split() + if len(strs) == 0: + continue + if strs[0] == "accept": + for present_state in strs[1:]: + self.accept_state.append(self.state_id[present_state]) + continue + else: + present_state = strs.pop(0) + read_char = strs.pop(0) + write_char = strs.pop(0) + direction = strs.pop(0) + next_state = strs.pop(0) + if add_to_dict(self.state_id, present_state, self.num_states): + self.num_states = self.num_states + 1 + if add_to_dict(self.state_id, next_state, self.num_states): + self.num_states = self.num_states + 1 + if add_to_dict(self.alph_id, read_char, self.num_alphs): + self.num_alphs = self.num_alphs + 1 + if add_to_dict(self.alph_id, write_char, self.num_alphs): + self.num_alphs = self.num_alphs + 1 + self.state_table = init_2d_list(self.num_states, self.num_alphs, -1) + self.write_table = init_2d_list(self.num_states, self.num_alphs, '_') + self.dir_table = init_2d_list(self.num_states, self.num_alphs, 0) + fin.close() + + def makeTransitionTables(self): + fin = open(self.input_file_name, 'r') + line = fin.readline() + for line in fin: + strs = line.split() + if len(strs) == 0: + continue + if strs[0] == "accept": + continue + else: + present_state = strs.pop(0) + read_char = strs.pop(0) + write_char = strs.pop(0) + direction = strs.pop(0) + next_state = strs.pop(0) + + # find id's + present_state_id = self.state_id[present_state] + next_state_id = self.state_id[next_state] + read_char_id = self.alph_id[read_char] + if direction == "l": + dir_id = -1 + elif direction == "r": + dir_id = +1 + else: + dir_id = 0 + + # fill transition tables with id's + self.state_table[present_state_id][read_char_id] = next_state_id + self.write_table[present_state_id][read_char_id] = write_char + self.dir_table[present_state_id][read_char_id] = dir_id + + fin.close() + + def turingSimulator(self): + f = open("log.txt", 'w') + f.close() + + present_state_id = 0 + self.displayTape(present_state_id) + while True: + read_char_id = self.alph_id[self.tape[self.ptr]] + dir_id = self.dir_table[present_state_id][read_char_id] + self.tape = self.tape[0:self.ptr] + self.write_table[present_state_id][read_char_id] + self.tape[self.ptr+1:] + present_state_id = self.state_table[present_state_id][read_char_id] + + if present_state_id == -1: + if len(self.accept_state) > 0: + print("\n", "> rejected", sep='', end='') + else: + print("\n", "> halted", sep='', end='') + break + + if present_state_id in self.accept_state: + print("\n", "> accepted", sep='', end='') + break + + self.ptr += dir_id + if self.ptr < 0: + self.tape = "_" + self.tape + self.ptr = 0 + if self.ptr >= len(self.tape): + self.tape = self.tape + "_" + self.displayTape(present_state_id) + diff --git a/turing_machine.cpp b/turing_machine.cpp index d314ca3..b3a2722 100644 --- a/turing_machine.cpp +++ b/turing_machine.cpp @@ -1,11 +1,24 @@ #include "turing_machine.h" -void TuringMachine::displayTape() { +void TuringMachine::displayTape(int present_state_id) { + std::ofstream flog("log.txt", std::ios_base::app); + std::cout << "\r" << tape.substr(0, ptr); // display tape contents before the pointer head + flog << "\r" << tape.substr(0, ptr); std::cout << "[" << tape[ptr] << "]"; // display tape content under the pointer head + flog << "[" << tape[ptr] << "]"; std::cout << tape.substr(ptr + 1); // display tape contents after the pointer head + flog << tape.substr(ptr + 1); + + std::string state_name; + for (auto it = state_id.begin(); it != state_id.end(); ++it) + if (it->second == present_state_id) + state_name = it->first; + + std::cout << " " << state_name << " "; + flog << " " << state_name << " "; std::cout << std::flush; - usleep(200000); + _sleep(200); } int TuringMachine::parseFile() { @@ -47,6 +60,9 @@ int TuringMachine::parseFile() { dir_table = std::vector>(num_states, std::vector(num_alphs, 0)); ifs.close(); + + std::ofstream flog("log.txt"); + return 0; } @@ -89,7 +105,7 @@ void TuringMachine::makeTransitionTables(){ void TuringMachine::turingSimulator(){ int present_state_id = 0, read_char_id, dir_id = 0; - displayTape(); + displayTape(present_state_id); while(true){ read_char_id = alph_id.find(tape[ptr])->second; dir_id = dir_table[present_state_id][read_char_id]; @@ -116,6 +132,6 @@ void TuringMachine::turingSimulator(){ } if(ptr >= tape.size()) tape = tape + "_"; - displayTape(); + displayTape(present_state_id); } } \ No newline at end of file diff --git a/turing_machine.h b/turing_machine.h index b7da18d..163d7fd 100644 --- a/turing_machine.h +++ b/turing_machine.h @@ -37,7 +37,7 @@ class TuringMachine { num_alphs(0), ptr(0){}; - void displayTape(); + void displayTape(int); int parseFile(); //void initializeTables(); void makeTransitionTables();