Open In App

Turing Machine Simulator Using Python

Last Updated : 08 Jun, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Turing machines and deterministic finite automata (DFAs) are two fundamental concepts in computer science and automata theory. Both these concepts are used to model and analyze computational systems and are essential tools in understanding the limits of computation. A Turing machine is a theoretical model of a computing machine that was introduced by Alan Turing in 1936. It is a simple, but powerful, abstract machine that can simulate any algorithmic process. A deterministic finite automaton (DFA), on the other hand, is a simpler model of computation than a Turing machine.

Difference between DFA and Turing Machine 

  • A deterministic finite automaton (DFA) is a special case of a Turing machine. Every DFA is a Turing machine, but not every Turing machine is a DFA.
  • A Turing machine has an infinite tape, whereas a DFA has a limited number of input symbols, which is the major distinction between the two. This means that although a DFA has a defined set of states and can only understand regular languages, a Turing machine has an endless capacity for computation and data handling.
  • Turing machines are capable of mimicking a DFA’s behaviour, but they are also capable of much more. Turing machines, for instance, are capable of doing multiplication and division calculations as well as the recognition of non-standard languages. DFAs, in contrast, can only understand regular languages, a collection of languages that Turing machines can comprehend.

Required Modules

pip install tk

Steps

Let’s see how to create a simple Turing Machine Simulator. Below is the Python code which uses the Tkinter library to make the simulator more interactive: 

Step 1. Import necessary libraries and make the class for the application :

Python3




import tkinter as tk
from tkinter import messagebox
import webbrowser
  
class TuringMachineSimulator(tk.Tk):
  # All the required functions will go in this class
    
 if __name__ == '__main__':
    app = TuringMachineSimulator()
    app.mainloop()


Step 2. Creating GUI window 

super().__init__() calls the constructor of the parent class, which is typically tkinter.Tk in a GUI application. This line initializes the main application window. self.title(“Turing Machine Simulator”) sets the title of the main window to “Turing Machine Simulator”.self.geometry(“600×500”) sets the size of the main window to 600 pixels wide and 500 pixels tall. 

Python3




def __init__(self):
  super().__init__()
  self.title("Turing Machine Simulator")
  self.geometry("600x500")
  self.create_welcome_page()


Step 3. Creating a Welcome Page :

This function creates the welcome page of the simulator, with a label and a button to proceed to the options page. It sets the background color of the page and adds a label and a button to the window.

Python3




def create_welcome_page(self):
    self.configure(bg="#1E90FF")
  
    tk.Label(self, text="Turing Machine Simulator",
             bg="#1E90FF", fg="white",
             font=('Helvetica', 32, "bold")).pack(pady=50)
  
    tk.Button(self,
              text="Get Started",
              bg="#FFFACD",
              font=('sans-serif', 22, "bold"),
              command=self.create_options_page).pack(pady=50)
  
    self.credits()


Step 4. Creating an Option Page 

This function creates the options page of the simulator, where the user can select the type of Turing machine to simulate. It clears the previous page (if any), sets the background color of the page, adds a label and radio buttons to the window, and adds a button to proceed to the input page.

Python3




def create_options_page(self):
    for widget in self.winfo_children():
        widget.destroy()
        self.configure(bg="#ADD8E6")
  
        tk.Label(self, text="Select an option:", bg="#ADD8E6",
                 font=('Verdana', 16)).pack(pady=20)
  
        options = [
          ("String should accept odd one's and even zero's", 0),
           ("String should accept even one's and odd zero's", 1),
            ("String should accept even one's and even zero's", 2),
           ("String should accept odd one's and odd zero's", 3)]
        self.selected_option = tk.IntVar()
  
        for option, value in options:
            tk.Radiobutton(self, text=option, bg="#ADD8E6", font=(
                'Verdana', 12), 
                      variable=self.selected_option, 
                      value=value).pack(pady=10)
  
            tk.Button(self, text="Next", bg="#FFFACD", font=(
                'sans-serif', 12), 
                   command=self.create_input_page).pack(pady=30)
  
            self.credits()


Step 5. Creating an Input Page 

This function creates the input page of the simulator, where the user can input the string to be checked by the selected Turing machine. It clears the previous page (if any), sets the background colour of the page, adds a label and an entry field to the window, and adds a button to check the input string.

Python3




def create_input_page(self):
    for widget in self.winfo_children():
        widget.destroy()
  
    self.configure(bg="#90EE90")
    tk.Label(self, text="Enter a string:", bg="#90EE90",
             font=('Verdana', 16)).pack(pady=20)
  
    self.string_input = tk.Entry(self, font=("Calibri", 14))
    self.string_input.pack(pady=10)
  
    tk.Button(self, text="Check", bg="#FFFACD", font=(
        'sans-serif', 12), command=self.check_string).pack(pady=30)
  
    self.credits()


Step 6. Creating Function Check the input String

This function checks the input string using the selected Turing machine and displays the result in a message box.It calls the appropriate Turing machine function based on the selected option and input string and displays the result in a message box. It also adds buttons to restart or exit the simulator. These are the Turing machines implemented by the simulator to check the input strings. They take an input string as an argument and return True if the input string is accepted by the corresponding Turing machine, and False otherwise. Each function implements a different Turing machine based on the requirement specified in the corresponding option.

Python3




def check_string(self):
        string = self.string_input.get()
        option = self.selected_option.get()
        if option == 0:
            if self.accepts_odd_ones_even_zeros(string):
                messagebox.showinfo("Result"
                          f"The string '{string}' is accepted.")
            else:
                messagebox.showinfo("Result"
                          f"The string '{string}' is not accepted.")
        elif option == 1:
            if self.accepts_even_ones_odd_zeros(string):
                messagebox.showinfo("Result"
                             f"The string '{string}' is accepted.")
            else:
                messagebox.showinfo("Result"
                    f"The string '{string}' is not accepted.")
        elif option == 2:
            if self.accepts_even_ones_even_zeros(string):
                messagebox.showinfo("Result"
                     f"The string '{string}' is accepted.")
            else:
                messagebox.showinfo("Result"
                    f"The string '{string}' is not accepted.")
        elif option == 3:
            if self.accepts_odd_ones_odd_zeros(string):
                messagebox.showinfo("Result"
                    f"The string '{string}' is accepted.")
            else:
                messagebox.showinfo("Result"
                          f"The string '{string}' is not accepted.")
                  
        restart_button = tk.Button(self, text='Restart',
                          font=('sans-serif', 12), command=self.restart)
        restart_button.pack(side="left", padx=115, pady=30)
          
        exit_button = tk.Button(self, text='Exit', padx=10,
                          font=('sans-serif', 12), command=self.exit)
        exit_button.pack(side="left", padx=125, pady=30)
      
    def accepts_odd_ones_even_zeros(self, string):
        state = 0
        for symbol in string:
            if state == 0:
                if symbol == '0':
                    state = 2
                elif symbol == '1':
                    state = 1
                else:
                    return False
            elif state == 1:
                if symbol == '0':
                    state = 3
                elif symbol == '1':
                    state = 0
                else:
                    return False
            elif state == 2:
                if symbol == '0':
                    state = 0
                elif symbol == '1':
                    state = 3
                else:
                    return False
            elif state == 3:
                if symbol == '0':
                    state = 1
                elif symbol == '1':
                    state = 2
                else:
                    return False
        return state == 1
  
    def accepts_even_ones_odd_zeros(self, string):
        state = 0
        for symbol in string:
            if state == 0:
                if symbol == '0':
                    state = 2
                elif symbol == '1':
                    state = 1
                else:
                    return False
            elif state == 1:
                if symbol == '0':
                    state = 3
                elif symbol == '1':
                    state = 0
                else:
                    return False
            elif state == 2:
                if symbol == '0':
                    state = 0
                elif symbol == '1':
                    state = 3
                else:
                    return False
            elif state == 3:
                if symbol == '0':
                    state = 1
                elif symbol == '1':
                    state = 2
                else:
                    return False
        return state == 2
  
    def accepts_even_ones_even_zeros(self, string):
        state = 0
        for symbol in string:
            if state == 0:
                if symbol == '0':
                    state = 1
                elif symbol == '1':
                    state = 2
                else:
                    return False
            elif state == 1:
                if symbol == '0':
                    state = 0
                elif symbol == '1':
                    state = 3
                else:
                    return False
            elif state == 2:
                if symbol == '0':
                    state = 3
                elif symbol == '1':
                    state = 0
                else:
                    return False
            elif state == 3:
                if symbol == '0':
                    state = 2
                elif symbol == '1':
                    state = 1
                else:
                    return False
        return state == 0
      
    def accepts_odd_ones_odd_zeros(self, string):
        state = 0
        for symbol in string:
            if state == 0:
                if symbol == '0':
                    state = 2
                elif symbol == '1':
                    state = 1
                else:
                    return False
            elif state == 1:
                if symbol == '0':
                    state = 3
                elif symbol == '1':
                    state = 0
                else:
                    return False
            elif state == 2:
                if symbol == '0':
                    state = 0
                elif symbol == '1':
                    state = 3
                else:
                    return False
            elif state == 3:
                if symbol == '0':
                    state = 1
                elif symbol == '1':
                    state = 2
                else:
                    return False
        return state == 3


7. Creating ‘credits()’ function and function to restart and exit the application 

The restart function is a method of the TuringMachineSimulator class that is called when the user clicks the “Restart” button. It destroys all the widgets on the current page and then creates the welcome page again by calling the create_welcome_page method. The exit function is also a method of the TuringMachineSimulator class that is called when the user clicks the “Exit” button. It calls the destroy method on the Tk instance to exit the application. The credits function is a method of the TuringMachineSimulator class that creates a label at the bottom of the page with a hyperlink to the GitHub repository of the project. When the user clicks the hyperlink, the repository is opened in their default web browser using the webbrowser module.

Python3




def restart(self):
    for widget in self.winfo_children():
        widget.destroy()
    self.create_welcome_page()
 
def exit(self):
    for widget in self.winfo_children():
        widget.destroy()
      
    self.exit_frame = tk.Frame(self)
    self.exit_frame.pack(pady=30)
      
    self.exit_label = tk.Label(self.exit_frame
                     , font=('Helvetica', 24))
      
    self.exit_label.config(text='Thank' 
                +'You for using the Simulator')
    self.exit_label.pack()
      
    self.after(1000,self.destroy)
      
def credits(self):
    made_by_label = tk.Label(self, text='GFG'
                             font=('Helvetica', 10)
                       , fg='blue', cursor='hand2')
    made_by_label.pack(side='bottom', pady=10)
    made_by_label.bind('<Button-1>'
    , lambda e: webbrowser.open_new("https:"
                     +"//www.geeksforgeeks.org/"))


Complete Code 

Python3




import tkinter as tk
from tkinter import messagebox
import webbrowser
  
  
class TuringMachineSimulator(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Turing Machine Simulator")
        self.geometry("600x500")
        self.create_welcome_page()
  
    def create_welcome_page(self):
        self.configure(bg="#1E90FF")
  
        tk.Label(self, text="Turing Machine Simulator", bg="#1E90FF",
                 fg="white"
                    font=('Helvetica', 32, "bold")).pack(pady=50)
  
        tk.Button(self, text="Get Started", bg="#FFFACD", font=(
            'sans-serif', 22, "bold"), 
             command=self.create_options_page).pack(pady=50)
  
        self.credits()
  
    def create_options_page(self):
        for widget in self.winfo_children():
            widget.destroy()
        self.configure(bg="#ADD8E6")
  
        tk.Label(self, text="Select an option:", bg="#ADD8E6",
                 font=('Verdana', 16)).pack(pady=20)
  
        options = [
          ("String should accept odd one's and even zero's", 0),
          ("String should accept even one's and odd zero's", 1),
          ("String should accept even one's and even zero's", 2),
          ("String should accept odd one's and odd zero's", 3)]
        self.selected_option = tk.IntVar()
  
        for option, value in options:
            tk.Radiobutton(self, text=option, bg="#ADD8E6", font=(
                'Verdana', 12), 
                 variable=self.selected_option, value=value).pack(pady=10)
  
        tk.Button(self, text="Next", bg="#FFFACD", font=(
            'sans-serif', 12), 
             command=self.create_input_page).pack(pady=30)
  
        self.credits()
  
    def create_input_page(self):
        for widget in self.winfo_children():
            widget.destroy()
  
        self.configure(bg="#90EE90")
        tk.Label(self, text="Enter a string:", bg="#90EE90",
                 font=('Verdana', 16)).pack(pady=20)
  
        self.string_input = tk.Entry(self, font=("Calibri", 14))
        self.string_input.pack(pady=10)
  
        tk.Button(self, text="Check", bg="#FFFACD", font=(
            'sans-serif', 12),
                  command=self.check_string).pack(pady=30)
  
        self.credits()
  
    def check_string(self):
        string = self.string_input.get()
        option = self.selected_option.get()
        if option == 0:
            if self.accepts_odd_ones_even_zeros(string):
                messagebox.showinfo(
                    "Result", f"The string '{string}' is accepted.")
            else:
                messagebox.showinfo(
                    "Result", f"The string '{string}' is not accepted.")
        elif option == 1:
            if self.accepts_even_ones_odd_zeros(string):
                messagebox.showinfo(
                    "Result", f"The string '{string}' is accepted.")
            else:
                messagebox.showinfo(
                    "Result", f"The string '{string}' is not accepted.")
        elif option == 2:
            if self.accepts_even_ones_even_zeros(string):
                messagebox.showinfo(
                    "Result", f"The string '{string}' is accepted.")
            else:
                messagebox.showinfo(
                    "Result", f"The string '{string}' is not accepted.")
        elif option == 3:
            if self.accepts_odd_ones_odd_zeros(string):
                messagebox.showinfo(
                    "Result", f"The string '{string}' is accepted.")
            else:
                messagebox.showinfo(
                    "Result", f"The string '{string}' is not accepted.")
  
        restart_button = tk.Button(self, text='Restart', font=(
            'sans-serif', 12), command=self.restart)
        restart_button.pack(side="left", padx=115, pady=30)
  
        exit_button = tk.Button(self, text='Exit', padx=10, font=(
            'sans-serif', 12), command=self.exit)
        exit_button.pack(side="left", padx=125, pady=30)
  
    def accepts_odd_ones_even_zeros(self, string):
        state = 0
        for symbol in string:
            if state == 0:
                if symbol == '0':
                    state = 2
                elif symbol == '1':
                    state = 1
                else:
                    return False
            elif state == 1:
                if symbol == '0':
                    state = 3
                elif symbol == '1':
                    state = 0
                else:
                    return False
            elif state == 2:
                if symbol == '0':
                    state = 0
                elif symbol == '1':
                    state = 3
                else:
                    return False
            elif state == 3:
                if symbol == '0':
                    state = 1
                elif symbol == '1':
                    state = 2
                else:
                    return False
        return state == 1
  
    def accepts_even_ones_odd_zeros(self, string):
        state = 0
        for symbol in string:
            if state == 0:
                if symbol == '0':
                    state = 2
                elif symbol == '1':
                    state = 1
                else:
                    return False
            elif state == 1:
                if symbol == '0':
                    state = 3
                elif symbol == '1':
                    state = 0
                else:
                    return False
            elif state == 2:
                if symbol == '0':
                    state = 0
                elif symbol == '1':
                    state = 3
                else:
                    return False
            elif state == 3:
                if symbol == '0':
                    state = 1
                elif symbol == '1':
                    state = 2
                else:
                    return False
        return state == 2
  
    def accepts_even_ones_even_zeros(self, string):
        state = 0
        for symbol in string:
            if state == 0:
                if symbol == '0':
                    state = 1
                elif symbol == '1':
                    state = 2
                else:
                    return False
            elif state == 1:
                if symbol == '0':
                    state = 0
                elif symbol == '1':
                    state = 3
                else:
                    return False
            elif state == 2:
                if symbol == '0':
                    state = 3
                elif symbol == '1':
                    state = 0
                else:
                    return False
            elif state == 3:
                if symbol == '0':
                    state = 2
                elif symbol == '1':
                    state = 1
                else:
                    return False
        return state == 0
  
    def accepts_odd_ones_odd_zeros(self, string):
        state = 0
        for symbol in string:
            if state == 0:
                if symbol == '0':
                    state = 2
                elif symbol == '1':
                    state = 1
                else:
                    return False
            elif state == 1:
                if symbol == '0':
                    state = 3
                elif symbol == '1':
                    state = 0
                else:
                    return False
            elif state == 2:
                if symbol == '0':
                    state = 0
                elif symbol == '1':
                    state = 3
                else:
                    return False
            elif state == 3:
                if symbol == '0':
                    state = 1
                elif symbol == '1':
                    state = 2
                else:
                    return False
        return state == 3
  
    def restart(self):
        for widget in self.winfo_children():
            widget.destroy()
        self.create_welcome_page()
  
    def exit(self):
        for widget in self.winfo_children():
            widget.destroy()
  
        self.exit_frame = tk.Frame(self)
        self.exit_frame.pack(pady=30)
  
        self.exit_label = tk.Label(self.exit_frame,
                                   font=('Helvetica', 24))
  
        self.exit_label.config(text='Thank You for"+ 
                "using the Simulator')
        self.exit_label.pack()
  
        self.after(1000, self.destroy)
  
    def credits(self):
        made_by_label = tk.Label(self, text='GFG', font=(
            'Helvetica', 10), fg='blue', cursor='hand2')
        made_by_label.pack(side='bottom', pady=10)
        made_by_label.bind(
            '<Button-1>', lambda e: webbrowser.open_new("https:"
                               +"//www.geeksforgeeks.org/"))
  
  
if __name__ == '__main__':
    app = TuringMachineSimulator()
    app.mainloop()


Output 

Turing Machine Simulator Output in Python

GIF



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads