Quick Start Guide

This guide provides a quick introduction to StateTracker, a Python library for creating composable states with unidirectional value propagation.

Installation

Install from PyPI:

pip install statetracker

Basic Usage

All states must be created within a Manager context:

from statetracker import Manager, State

with Manager():
    A = State(num_values=3, name="A")
    print(list(A))
[0, 1, 2]

State Operations

Product (Cartesian Product)

Use product to create Cartesian products:

from statetracker import Manager, State, product

with Manager():
    A = State(num_values=2, name="A")
    B = State(num_values=3, name="B")
    C = product([A, B], name="C")  # 6 values

    for _ in C:
        C.print_states()
C=0, A=0, B=0
C=1, A=1, B=0
C=2, A=0, B=1
C=3, A=1, B=1
C=4, A=0, B=2
C=5, A=1, B=2

Stack (Disjoint Union)

Use stack to create disjoint unions where only one state is active at a time:

from statetracker import Manager, State, stack

with Manager():
    A = State(num_values=2, name="A")
    B = State(num_values=3, name="B")
    C = stack([A, B], name="C")  # 5 values

    for _ in C:
        # Only one of A or B is active at a time (the other is None)
        C.print_states()
C=0, A=0, B=None
C=1, A=1, B=None
C=2, A=None, B=0
C=3, A=None, B=1
C=4, A=None, B=2

Slicing

Use Python slice syntax to select subsets of values:

from statetracker import Manager, State

with Manager():
    A = State(num_values=10, name="A")
    B = A[2:5].named("B")   # Values 2, 3, 4
    C = A[::-1].named("C")  # Reversed: 9, 8, 7, ..., 0

    print(f"A has {A.num_values} values")
    print(f"\nB (slice [2:5]) has {B.num_values} values: {list(B)}")
    for _ in B:
        B.print_states()

    print(f"\nC (reversed) has {C.num_values} values: {list(C)}")
    for _ in C:
        C.print_states()
A has 10 values

B (slice [2:5]) has 3 values: [0, 1, 2]
B=0, A=2
B=1, A=3
B=2, A=4

C (reversed) has 10 values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
C=0, A=9
C=1, A=8
C=2, A=7
C=3, A=6
C=4, A=5
C=5, A=4
C=6, A=3
C=7, A=2
C=8, A=1
C=9, A=0

Value Propagation

StateTracker uses unidirectional value propagation. Setting a child state’s value automatically updates all parent states:

from statetracker import Manager, State, product

with Manager():
    A = State(num_values=2, name="A")
    B = State(num_values=3, name="B")
    C = product([A, B])

    C.value = 5  # Set child value
    print("After setting C.value = 5:")
    print(f"A.value = {A.value}")  # 1 (automatically updated)
    print(f"B.value = {B.value}")  # 2 (automatically updated)
After setting C.value = 5:
A.value = 1
B.value = 2

Inspecting States

Use get_states() and print_states() to conveniently view all state values at once:

from statetracker import Manager, State, product

with Manager():
    A = State(num_values=2, name="A")
    B = State(num_values=3, name="B")
    C = product([A, B], name="C")

    C.value = 5
    C.print_states()  # Print all values in one line

    values = C.get_states()  # Get values as a dictionary
    print(values)
C=5, A=1, B=2
{'C': 5, 'A': 1, 'B': 2}

Visualization

Use print_dag() to visualize state dependencies:

from statetracker import Manager, State, product

with Manager():
    A = State(num_values=2, name="A")
    B = State(num_values=3, name="B")
    C = product([A, B], name="C")

    C.print_dag()
C (counter, io=0, n=6)
+-- [op=Product]
    +-- A (counter, io=0, n=2)
    +-- B (counter, io=0, n=3)

Next Steps

  • See Core Concepts for a deeper understanding of state algebra

  • Explore the Operations reference for all available operations

  • Check the API Reference for detailed function documentation