Skip to main content

Object-oriented Turing machine emulator

Project description

puring

PyPI version Python versions License

An elegant, object-oriented Turing machine emulator in Python.

puring provides a simple and intuitive API for defining and running Turing machines, making it ideal for educational purposes, theoretical computer science explorations, and algorithmic experiments.

Features

  • Object-Oriented Design: Define states, tapes, and machines as distinct objects.
  • Infinite Tape: The tape is implemented as a sparse array, dynamically growing in either direction as needed.
  • Flexible Alphabet: Use strings, numbers, or any other Python object as symbols on the tape.
  • Clear Transition Rules: The transition table is a clean, readable Python dictionary.
  • Helper Utilities: Quickly generate unique states and control machine execution.

Installation

Install puring directly from PyPI:

pip install puring

Quick Start

Let's create a simple Turing machine that inverts a binary string (flips 0s to 1s and 1s to 0s).

from puring import Turing, Tape, States, R, S

# 1. Define states for the machine.
# We need one main state. The halt condition is handled by the 'S' (Stop) action.
q0, = States(1)

# 2. Define the machine's alphabet.
alphabet = [0, 1]

# 3. Create the transition table (the machine's "program").
# The structure is: {state: {read_symbol: [write_symbol, move_direction, next_state]}}
table = {
    q0: {
        # If we read a 0, write a 1, move Right, and stay in state q0.
        0: [1, R, q0],
        # If we read a 1, write a 0, move Right, and stay in state q0.
        1: [0, R, q0],
        # If we read a blank symbol (None), Stop the machine.
        None: [None, S, q0]
    }
}

# 4. Instantiate the Turing machine.
# The initial state is automatically inferred from the first key in the table.
turing_machine = Turing(alphabet=alphabet, table=table)

# 5. Create a tape with an initial sequence.
# The input is a string, but we process each character as an integer.
tape = Tape("1101001", process_as=int)

# 6. Run the machine on the tape, starting from the beginning.
print(f"Initial tape: {tape}")
tape.run_at_start(turing_machine)
print(f"Final tape:   {tape}")

# Expected output:
# Initial tape: 1 1 0 1 0 0 1
# Final tape:   0 0 1 0 1 1 0

Core Concepts

States(n)

A convenience function that returns a tuple of n unique State objects. These objects act as keys in the transition table.

q0, q1, q_accept = States(3)

Turing(alphabet, table, ...)

The main machine class.

  • alphabet: A list of valid symbols the machine can read and write.
  • table: A dictionary defining the transition function. Its keys are State objects.
  • state: (Optional) The initial state. Defaults to the first state found in the table.
  • iteration_limit: (Optional) A safety limit to prevent true infinite loops and raise a RuntimeError. Defaults to 100000.

Tape(tape, process_as)

Represents the machine's tape.

  • tape: A list or str containing the initial symbols.
  • process_as: A function (like int or str) to apply to each item in the initial tape sequence.
  • run(turing, index): Runs the machine starting at a specific index.
  • run_at_start(turing, offset=0): A helper to run from the start of the written tape.
  • run_at_end(turing, offset=0): A helper to run from the end of the written tape.

The Transition Table

The table is a nested dictionary with the following structure:

{ state: { read_symbol: [write_symbol, move_action, next_state] } }

Actions

Actions control the machine's movement and execution.

  • R: Move the tape head one cell to the Right.
  • L: Move the tape head one cell to the Left.
  • N: Do Not move the tape head.
  • S: Stop the machine execution successfully.
  • Let: A special symbol for the "write" instruction. It means Let the symbol on the tape remain unchanged, which is useful if you only want to move the head or change state.

Advanced Usage

Matching Multiple Symbols

You can use a tuple of symbols as a key in the transition table to match any symbol within that tuple. This is a convenient way to group transitions that share the same outcome.

Here's a machine that moves right until it finds a 0.

from puring import *

q0, = States(1)

# If the machine reads a 1 or a 2, it will perform the same action.
table = {
    q0: {
        (1, 2): [Let, R, q0], # If 1 or 2, leave it, move Right, stay in q0
        0: [Let, S, q0],      # If 0, leave it and Stop
    }
}

turing_machine = Turing(alphabet=[0, 1, 2], table=table)
tape = Tape([1, 2, 1, 2, 2, 1, 0, 1, 2], process_as=int)

tape.run_at_start(turing_machine)

# The machine will stop when the head is over the '0'.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

puring-0.1.4.tar.gz (5.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

puring-0.1.4-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

File details

Details for the file puring-0.1.4.tar.gz.

File metadata

  • Download URL: puring-0.1.4.tar.gz
  • Upload date:
  • Size: 5.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for puring-0.1.4.tar.gz
Algorithm Hash digest
SHA256 8cde79368252698de844cfad9022accc8be3b4a67ec85bdbe4b56c565655aa17
MD5 a85313be7cebcd5c50498a856acfa076
BLAKE2b-256 7f87b6f3a30a9ac4525f15fe4e6cfe2eafd85d4ba1e857d922fa988b09976a00

See more details on using hashes here.

File details

Details for the file puring-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: puring-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 9.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for puring-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 f851210373098126d0c578c468b10793523081209ce5a56cb341b38a2077cf67
MD5 b83c674cef1fad9887f15498f99c2f3b
BLAKE2b-256 3896aa9558b18f4b3884d46f79f57326681ef39bbf5e1933a98d287de65570b1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page