================================================================================
                            PBITLANG USER MANUAL
                                Version 1.0

       A Domain-Specific Language for Thermodynamic Computing Hamiltonians
================================================================================

TABLE OF CONTENTS
-----------------
1.  Introduction
2.  Installation
3.  Quick Start
4.  Language Basics
5.  Spin Types and Their Physics
6.  Lattice Geometries
7.  Writing Hamiltonians
8.  Standard Library Models
9.  Physics Validation
10. Compilation and Code Generation
11. Integration with PHAL
12. Command Line Interface
13. Advanced Topics
14. Scientific Background
15. Troubleshooting
16. Reference


================================================================================
1. INTRODUCTION
================================================================================

PbitLang is a domain-specific language (DSL) designed for expressing energy
functions (Hamiltonians) for thermodynamic computing systems. It compiles to
PHAL (P-bit Hardware Abstraction Layer) Hamiltonian objects, enabling execution
on P-bit hardware or simulators.

Why PbitLang?
-------------
Writing Hamiltonians for thermodynamic computing by hand is error-prone:

  - Coupling matrices must be symmetric for undirected interactions
  - Different spin types (Ising, Potts, XY) require different interaction forms
  - Lattice geometries have specific neighbor relations
  - Physical constraints must be enforced at compile time

PbitLang solves these problems by:

  1. Enforcing physical correctness at compile time
  2. Providing high-level abstractions for common patterns
  3. Generating optimized PHAL Hamiltonians automatically
  4. Warning about physics issues (frustration, critical temperatures)


================================================================================
2. INSTALLATION
================================================================================

Requirements:
  - Python 3.9 or higher
  - No external dependencies for core functionality

Installation from source:

    cd pbitlang
    pip install .

Installation with PHAL integration:

    pip install .[phal]

Installation for development:

    pip install -e .[dev]


================================================================================
3. QUICK START
================================================================================

3.1 Your First Hamiltonian
--------------------------

Create a file named "my_ising.pbit":

    // Simple Ising chain with ferromagnetic coupling
    hamiltonian MyIsing(n: int, J: real = 1.0)
        -> ising on chain(n, periodic) {

        coupling: sum((i, j) in neighbors) {
            -J * s[i] * s[j]
        }
    }

3.2 Compile and Use
-------------------

From Python:

    import pbitlang
    import phal

    # Compile the source
    source = open("my_ising.pbit").read()
    result = pbitlang.compile(source, params={"n": 10, "J": 1.0})

    # Get the PHAL Hamiltonian
    hamiltonian = result.to_phal()

    # Sample on a device
    device = phal.get_device("numpy:0")
    samples = device.sample(hamiltonian, num_samples=1000, beta=2.0)

    print(f"Mean energy: {samples.mean_energy}")

From command line:

    pbitlang compile my_ising.pbit --param n=10 --param J=1.0 --target=phal

3.3 Using Standard Library Models
---------------------------------

PbitLang includes pre-built physics models:

    from pbitlang.stdlib import IsingChain, Ising2D, Potts2D, MaxCut

    # Create a 10-spin Ising chain
    chain = IsingChain(n=10, J=1.0, h=0.1)
    hamiltonian = chain.to_phal()

    # Create a 2D Ising model
    ising2d = Ising2D(nx=8, ny=8, J=1.0)

    # Get critical temperature info
    print(f"Critical temperature: {ising2d.critical_temperature}")


================================================================================
4. LANGUAGE BASICS
================================================================================

4.1 Comments
------------

    // Single line comment
    # Alternative single line comment

    /* Multi-line
       comment */

    /// Documentation comment (attached to next declaration)

4.2 Literals
------------

    Integers:    42, -17, 0x2A, 0b101010
    Reals:       3.14, 2.5e-3, -1.0
    Booleans:    true, false
    Strings:     "hello", 'world'

4.3 Parameters and Constants
----------------------------

Parameters are values provided at compile time:

    param n: int                    // Required parameter
    param J: real = 1.0             // With default value
    param q: int where q >= 2       // With constraint

Constants are computed once:

    const pi: real = 3.14159265359
    const k_B: real = 8.617333262e-5  // Boltzmann constant in eV/K

4.4 Local Variables
-------------------

Use 'let' for local bindings within expressions:

    let J_eff = J / temperature
    let distance_factor = 1.0 / distance(i, j)^2

4.5 Operators
-------------

    Arithmetic:    + - * / ^ (power) % (modulo)
    Comparison:    == != < > <= >=
    Logical:       and or not
    Range:         0..n (exclusive), 0...n (inclusive)


================================================================================
5. SPIN TYPES AND THEIR PHYSICS
================================================================================

PbitLang supports five spin types, each with specific physical meaning:

5.1 Ising Spins
---------------

    spin_type: ising
    Values:    s in {-1, +1}

Classical Ising spins represent magnetic moments that can point up (+1) or
down (-1). They are the most common choice for optimization problems.

Valid operations:
    s[i] * s[j]          // Spin-spin coupling
    s[i]                 // External field coupling

Example:
    hamiltonian Ferromagnet(n: int, J: real, h: real)
        -> ising on chain(n) {
        coupling: sum((i,j) in neighbors) { -J * s[i] * s[j] }
        field:    sum(i in sites) { -h * s[i] }
    }

5.2 Binary Variables
--------------------

    spin_type: binary
    Values:    x in {0, 1}

Binary variables are natural for combinatorial optimization (QUBO problems).
They relate to Ising spins by: x = (1 + s) / 2

Valid operations:
    x[i] * x[j]          // Quadratic coupling
    x[i]                 // Linear term
    (1 - x[i])           // Negation

Example:
    hamiltonian QUBO(Q: matrix[real, n, n])
        -> binary on complete(n) {
        energy: sum((i,j) in all_pairs) { Q[i,j] * x[i] * x[j] }
              + sum(i in sites) { Q[i,i] * x[i] }
    }

5.3 Potts Spins
---------------

    spin_type: potts(q)
    Values:    sigma in {0, 1, ..., q-1}

q-state Potts model generalizes Ising to q discrete states. Commonly used
for graph coloring, clustering, and phase transitions.

Valid operations:
    delta(sigma[i], sigma[j])    // Kronecker delta: 1 if equal, 0 otherwise

Example:
    hamiltonian GraphColoring(n: int, q: int = 3)
        -> potts(q) on graph(G)
        where q >= 2 {
        // Penalize adjacent vertices with same color
        energy: sum((i,j) in edges) { delta(sigma[i], sigma[j]) }
    }

5.4 Clock Spins
---------------

    spin_type: clock(q)
    Values:    theta = 2*pi*k/q for k in {0, 1, ..., q-1}

Discrete approximation to continuous angles. With q=2, reduces to Ising.
With large q, approximates the XY model.

Valid operations:
    cos(theta[i] - theta[j])     // Cosine coupling (XY-like)

Example:
    hamiltonian DiscreteXY(n: int, q: int = 16)
        -> clock(q) on square(n, n) {
        coupling: sum((i,j) in neighbors) { -cos(theta[i] - theta[j]) }
    }

5.5 Continuous Spins
--------------------

    spin_type: continuous
    Values:    theta in [0, 2*pi)

True continuous angles for the XY model and related systems.

Valid operations:
    cos(theta[i] - theta[j])     // Cosine coupling
    sin(theta[i] - theta[j])     // Sine coupling (chiral)

Example:
    hamiltonian XYModel(n: int, J: real = 1.0)
        -> continuous on square(n, n, periodic) {
        coupling: sum((i,j) in neighbors) { -J * cos(theta[i] - theta[j]) }
    }


================================================================================
6. LATTICE GEOMETRIES
================================================================================

6.1 One-Dimensional Lattices
----------------------------

Chain (1D):

    lattice L = chain(n)                    // Open boundaries
    lattice L = chain(n, periodic)          // Periodic boundaries
    lattice L = chain(n, boundary=open)     // Explicit open

Properties:
  - n sites
  - Each site has 2 neighbors (1 at boundaries for open)
  - Coordination number z = 2

6.2 Two-Dimensional Lattices
----------------------------

Square lattice:

    lattice L = square(nx, ny)              // Open boundaries
    lattice L = square(n, n, periodic)      // Torus topology

Properties:
  - nx * ny sites
  - Coordination number z = 4
  - Critical temperature: Tc = 2 / ln(1 + sqrt(2)) for Ising

Triangular lattice:

    lattice L = triangular(n)

Properties:
  - Coordination number z = 6
  - Frustrated for antiferromagnetic coupling
  - Critical temperature: Tc = 4 / ln(3) for Ising

Honeycomb lattice:

    lattice L = honeycomb(n)

Properties:
  - Coordination number z = 3
  - Bipartite structure (like graphene)
  - Critical temperature: Tc = 2 / ln(2 + sqrt(3)) for Ising

Kagome lattice:

    lattice L = kagome(n)

Properties:
  - Coordination number z = 4
  - Corner-sharing triangles
  - Highly frustrated for antiferromagnets

6.3 Three-Dimensional Lattices
------------------------------

Simple cubic:

    lattice L = cubic(nx, ny, nz)

Properties:
  - nx * ny * nz sites
  - Coordination number z = 6
  - Critical temperature: Tc approx 4.511 for Ising (numerical)

6.4 Special Graphs
------------------

Complete graph (all-to-all):

    lattice L = complete(n)

Properties:
  - Every pair of spins interacts
  - Mean-field limit as n -> infinity

Bipartite graph:

    lattice L = bipartite(n_visible, n_hidden)

Properties:
  - Two disjoint sets of spins
  - Edges only between sets
  - Natural for RBMs

Custom from edges:

    lattice L = from_edges([(0,1), (1,2), (0,2)])
    lattice L = from_adjacency(A)   // From adjacency matrix


================================================================================
7. WRITING HAMILTONIANS
================================================================================

7.1 Basic Structure
-------------------

    hamiltonian Name(parameters)
        -> spin_type on lattice
        [where constraints] {

        // Energy terms
    }

7.2 Sum Expressions
-------------------

The 'sum' construct iterates over index sets:

    // Over neighbor pairs
    sum((i, j) in neighbors) { -J * s[i] * s[j] }

    // Over all sites
    sum(i in sites) { -h * s[i] }

    // Over all pairs with condition
    sum((i, j) in all_pairs where i < j) { -J/r^2 * s[i] * s[j] }

    // Over a range
    sum(k in 0..n) { weights[k] * s[k] }

7.3 Built-in Functions
----------------------

For lattices:
    neighbors(L)         // Nearest-neighbor pairs
    next_neighbors(L)    // Next-nearest neighbors
    all_pairs(L)         // All (i,j) pairs with i < j
    sites(L)             // All site indices
    distance(i, j)       // Euclidean distance
    coordination(i)      // Number of neighbors

For spins:
    delta(sigma_i, sigma_j)     // Kronecker delta (Potts)
    cos(theta_i - theta_j)      // Cosine coupling
    sin(theta_i - theta_j)      // Sine coupling

Math functions:
    sqrt(x), abs(x), exp(x), log(x)
    sin(x), cos(x), tan(x)
    min(a, b), max(a, b)

7.4 Multiple Terms
------------------

Hamiltonians can have multiple labeled terms:

    hamiltonian FullIsing(n: int, J: real, J2: real, h: real)
        -> ising on chain(n) {

        // Nearest neighbor
        nn_coupling: sum((i,j) in neighbors) {
            -J * s[i] * s[j]
        }

        // Next-nearest neighbor
        nnn_coupling: sum((i,j) in next_neighbors) {
            -J2 * s[i] * s[j]
        }

        // External field
        field: sum(i in sites) {
            -h * s[i]
        }
    }

7.5 Constraints
---------------

Use 'where' clauses to enforce parameter constraints:

    hamiltonian Potts(n: int, q: int)
        -> potts(q) on square(n, n)
        where q >= 2 and q <= 100 {
        ...
    }

7.6 Annotations
---------------

Annotations modify validation and code generation:

    @model                  // Mark as standard model
    @directed               // Allow asymmetric coupling
    @validate(strict)       // Enable all runtime checks
    @validate(none)         // Disable runtime checks
    @sparse                 // Hint for sparse representation


================================================================================
8. STANDARD LIBRARY MODELS
================================================================================

PbitLang includes scientifically validated implementations of common models.

8.1 Ising Models
----------------

IsingChain(n, J=1.0, h=0.0):
    1D Ising chain with periodic boundaries.
    Exactly solvable; no phase transition in 1D.

Ising2D(nx, ny, J=1.0, h=0.0):
    2D Ising on square lattice.
    Critical temperature: Tc = 2.269... (Onsager's exact solution)

IsingTriangular(n, J=1.0, h=0.0):
    2D Ising on triangular lattice.
    Critical temperature: Tc = 3.641...

Usage:
    from pbitlang.stdlib import IsingChain, Ising2D

    model = Ising2D(nx=16, ny=16, J=1.0)
    print(f"Critical T: {model.critical_temperature}")
    hamiltonian = model.to_phal()

8.2 Potts Model
---------------

Potts2D(n, q=3, J=1.0):
    q-state Potts model on square lattice.
    First-order transition for q > 4.
    Critical temperature: Tc = 1 / ln(1 + sqrt(q))

Usage:
    from pbitlang.stdlib import Potts2D

    model = Potts2D(n=20, q=3)
    print(f"Transition type: {model.transition_type}")

8.3 Spin Glass
--------------

SherringtonKirkpatrick(n, seed=None):
    SK spin glass with Gaussian random couplings.
    Mean-field spin glass, replica symmetry breaking.

Usage:
    from pbitlang.stdlib import SherringtonKirkpatrick

    model = SherringtonKirkpatrick(n=100, seed=42)
    hamiltonian = model.to_phal()

8.4 Optimization Problems
-------------------------

MaxCut(edges, weights=None):
    Maximum cut problem on arbitrary graph.

    from pbitlang.stdlib import MaxCut

    edges = [(0,1), (1,2), (2,3), (3,0), (0,2)]
    weights = [1.0, 2.0, 1.0, 1.5, 0.5]
    model = MaxCut(edges=edges, weights=weights)

QUBO(Q):
    Quadratic Unconstrained Binary Optimization.

    from pbitlang.stdlib import QUBO
    import numpy as np

    Q = np.array([[1, -2, 0],
                  [0, 1, -1],
                  [0, 0, 2]])
    model = QUBO(Q=Q)

8.5 Neural Network Models
-------------------------

Hopfield(patterns):
    Hopfield associative memory network.
    Stores patterns using Hebbian learning rule.

    from pbitlang.stdlib import Hopfield
    import numpy as np

    # Store 3 patterns of 10 bits each
    patterns = np.array([
        [1, 1, 1, -1, -1, -1, 1, 1, 1, -1],
        [-1, 1, -1, 1, -1, 1, -1, 1, -1, 1],
        [1, -1, 1, -1, 1, -1, 1, -1, 1, -1],
    ])
    model = Hopfield(patterns=patterns)

RBM(n_visible, n_hidden, W, a, b):
    Restricted Boltzmann Machine.

    from pbitlang.stdlib import RBM
    import numpy as np

    model = RBM(
        n_visible=784,
        n_hidden=128,
        W=np.random.randn(784, 128) * 0.01,
        a=np.zeros(784),
        b=np.zeros(128)
    )


================================================================================
9. PHYSICS VALIDATION
================================================================================

PbitLang performs extensive compile-time and runtime validation to catch
physics errors before they cause incorrect results.

9.1 Compile-Time Checks
-----------------------

Symmetry validation:
    Coupling matrices for undirected models must be symmetric.
    J[i,j] must equal J[j,i].

    Error:
        Error [E0042]: Asymmetric coupling matrix
          --> model.pbit:15:5
           |
        15 |     let J = [[0, 1, 2], [1, 0, 1], [3, 1, 0]]
           |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
           |
           = note: Ising coupling matrices must be symmetric
           = note: Found J[0,2] = 2 but J[2,0] = 3
           = help: For directed interactions, use @directed

Type consistency:
    Each spin type has specific valid operations.

    Error:
        Error [E0031]: Invalid operation for spin type
          --> model.pbit:10:12
           |
        10 |     energy: sum((i,j) in neighbors) { sigma[i] * sigma[j] }
           |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
           |
           = note: Potts spins do not support multiplication
           = help: Use delta(sigma[i], sigma[j]) for Potts interactions

Parameter constraints:
    Constraints in 'where' clauses are checked at compile time.

    Error:
        Error [E0015]: Parameter constraint violated
          --> compile call
           |
           = note: Constraint 'q >= 2' failed with q = 1

9.2 Physics Warnings
--------------------

Frustration detection:
    The compiler warns about geometrically frustrated systems.

    Warning [W0017]: Frustrated system detected
      --> model.pbit:8:1
       |
     8 | hamiltonian AFTriangular(n: int, J: real)
       | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       |
       = note: Antiferromagnetic coupling on triangular lattice
               is geometrically frustrated
       = help: Consider using parallel tempering for sampling

Critical temperature:
    Near-critical simulations may converge slowly.

    Warning [W0023]: Near critical temperature
      --> runtime
       |
       = note: beta = 0.44 is near critical beta_c = 0.44
       = help: Critical slowing down may affect sampling

9.3 Runtime Validation
----------------------

Enable or disable runtime checks with annotations:

    @validate(strict)    // All checks enabled
    @validate(fast)      // Minimal checks
    @validate(none)      // No runtime checks

Runtime checks include:
  - NaN/Inf detection in energies
  - Matrix dimension verification
  - Value range validation


================================================================================
10. COMPILATION AND CODE GENERATION
================================================================================

10.1 The Compilation Pipeline
-----------------------------

    Source Code (.pbit)
         |
         v
    [1. Lexical Analysis]  -->  Tokens
         |
         v
    [2. Parsing]           -->  Abstract Syntax Tree
         |
         v
    [3. Type Checking]     -->  Typed AST
         |
         v
    [4. Physics Validation] --> Validated AST
         |
         v
    [5. Optimization]      -->  Optimized AST
         |
         v
    [6. Code Generation]   -->  PHAL Hamiltonian

10.2 Using the Compiler Programmatically
----------------------------------------

    import pbitlang

    source = '''
    hamiltonian Example(n: int, J: real)
        -> ising on chain(n) {
        coupling: sum((i,j) in neighbors) { -J * s[i] * s[j] }
    }
    '''

    # Compile with parameters
    result = pbitlang.compile(source, params={"n": 10, "J": 1.5})

    # Access compilation results
    print(f"Type: {result.hamiltonian_type}")
    print(f"Spins: {result.num_spins}")
    print(f"Warnings: {result.warnings}")

    # Get PHAL Hamiltonian
    hamiltonian = result.to_phal()

10.3 Compilation Options
------------------------

    result = pbitlang.compile(
        source,
        params={"n": 10},
        validate=True,           # Enable physics validation
        optimize=True,           # Enable optimizations
        sparse_threshold=0.1,    # Use sparse format below this density
    )

10.4 Output Formats
-------------------

PHAL Hamiltonian (default):
    hamiltonian = result.to_phal()

Python code:
    pbitlang compile model.pbit --target=python

JSON (serialized form):
    pbitlang compile model.pbit --target=json

LaTeX (documentation):
    pbitlang compile model.pbit --target=latex


================================================================================
11. INTEGRATION WITH PHAL
================================================================================

PbitLang is designed to work seamlessly with PHAL.

11.1 Basic Integration
----------------------

    import pbitlang
    import phal

    # Compile PbitLang to PHAL Hamiltonian
    source = '''
    hamiltonian MyModel(n: int, J: real)
        -> ising on square(n, n, periodic) {
        coupling: sum((i,j) in neighbors) { -J * s[i] * s[j] }
    }
    '''

    result = pbitlang.compile(source, params={"n": 8, "J": 1.0})
    hamiltonian = result.to_phal()

    # Use any PHAL device
    device = phal.get_device("numpy:0")
    samples = device.sample(hamiltonian, num_samples=1000, beta=0.5)

    print(f"Mean energy: {samples.mean_energy}")
    print(f"Best state: {samples.best_sample().state}")

11.2 Using with Different Backends
----------------------------------

    # NumPy simulator
    numpy_device = phal.get_device("numpy:0")

    # JAX accelerated (if available)
    jax_device = phal.get_device("jax:0")

    # Custom hardware (if registered)
    hardware_device = phal.get_device("extropic:0")

    # Same Hamiltonian works on all devices
    for device in [numpy_device, jax_device]:
        results = device.sample(hamiltonian, num_samples=100, beta=1.0)
        print(f"{device.full_id}: {results.mean_energy}")

11.3 Streaming Samples
----------------------

    device = phal.get_device("numpy:0")
    program = device.compile(hamiltonian)

    # Stream samples for real-time processing
    for sample in device.stream(program, beta=1.0):
        if sample.energy < threshold:
            print(f"Found low-energy state: {sample.state}")
            break


================================================================================
12. COMMAND LINE INTERFACE
================================================================================

PbitLang provides a command-line interface for common tasks.

12.1 Compilation
----------------

    # Compile to PHAL
    pbitlang compile model.pbit --param n=10 --param J=1.0

    # Compile with output file
    pbitlang compile model.pbit -o model.phal --param n=10

    # Generate Python code
    pbitlang compile model.pbit --target=python --param n=10

    # Generate LaTeX documentation
    pbitlang compile model.pbit --target=latex

12.2 Validation
---------------

    # Check syntax and physics
    pbitlang check model.pbit

    # Verbose output
    pbitlang check model.pbit --verbose

12.3 Information
----------------

    # Show language version
    pbitlang version

    # List standard library models
    pbitlang stdlib list

    # Show model documentation
    pbitlang stdlib info Ising2D


================================================================================
13. ADVANCED TOPICS
================================================================================

13.1 Custom Lattices
--------------------

Create custom connectivity from edge lists:

    hamiltonian CustomGraph(edges: list[(int,int)], J: real)
        -> ising on from_edges(edges) {
        coupling: sum((i,j) in edges) { -J * s[i] * s[j] }
    }

Or from an adjacency matrix:

    hamiltonian FromMatrix(A: matrix[real, n, n])
        -> ising on from_adjacency(A)
        where symmetric(A) {
        coupling: sum((i,j) in edges where A[i,j] != 0) {
            -A[i,j] * s[i] * s[j]
        }
    }

13.2 Distance-Dependent Couplings
---------------------------------

    hamiltonian LongRange(n: int, alpha: real)
        -> ising on chain(n)
        where alpha > 0 {

        // Power-law decay: J_ij ~ 1/r^alpha
        coupling: sum((i,j) in all_pairs where i < j) {
            -1.0 / distance(i, j)^alpha * s[i] * s[j]
        }
    }

13.3 Disorder and Randomness
----------------------------

Random couplings for spin glasses:

    import random from stdlib

    hamiltonian EdwardsAnderson(n: int)
        -> ising on cubic(n, n, n) {

        @quenched  // Random but fixed during sampling
        let J_bond = random.choice([-1.0, 1.0])

        coupling: sum((i,j) in neighbors) {
            -J_bond * s[i] * s[j]
        }
    }

13.4 Multi-Spin Interactions
----------------------------

Beyond pairwise interactions:

    hamiltonian ThreeBody(n: int, K: real)
        -> ising on triangular(n) {

        // Three-spin term on each triangle
        plaquette: sum((i,j,k) in triangles) {
            -K * s[i] * s[j] * s[k]
        }
    }

13.5 Composition and Reuse
--------------------------

Combine Hamiltonians:

    hamiltonian H1 = IsingChain(n=10, J=1.0)
    hamiltonian H2 = IsingChain(n=10, J=0.5)

    hamiltonian Combined = H1 + H2      // Sum of Hamiltonians
    hamiltonian Scaled = 2.0 * H1       // Scalar multiplication


================================================================================
14. SCIENTIFIC BACKGROUND
================================================================================

14.1 The Ising Model
--------------------

The Ising model describes interacting spins on a lattice:

    H = -sum_{<i,j>} J_ij * s_i * s_j - sum_i h_i * s_i

where s_i in {-1, +1} are spin variables, J_ij is the coupling between
spins i and j, and h_i is the external field at site i.

Key results:
  - 1D: No phase transition (Ising, 1925)
  - 2D square: Tc = 2J/k_B * 1/ln(1+sqrt(2)) (Onsager, 1944)
  - 3D: Tc numerically known, no exact solution

14.2 The Potts Model
--------------------

Generalization to q discrete states:

    H = -J * sum_{<i,j>} delta(sigma_i, sigma_j)

Key results:
  - 2D square: Tc = J/k_B * 1/ln(1+sqrt(q))
  - q <= 4: Second-order transition
  - q > 4: First-order transition

14.3 Frustration
----------------

Geometric frustration occurs when all interaction constraints cannot be
simultaneously satisfied. Example: antiferromagnetic triangle.

For three spins with J < 0:
  - Want adjacent spins anti-aligned
  - Triangle makes this impossible
  - Ground state is degenerate

Frustrated systems exhibit:
  - Ground state degeneracy
  - Slow dynamics
  - Spin glass behavior

14.4 Thermodynamic Sampling
---------------------------

P-bit hardware samples from the Boltzmann distribution:

    P(s) = exp(-beta * H(s)) / Z

where beta = 1/(k_B * T) is the inverse temperature and Z is the
partition function.

Low temperature (large beta):
  - Samples concentrate near ground state
  - Good for optimization

High temperature (small beta):
  - Uniform sampling
  - Good for exploration

14.5 References
---------------

[1] E. Ising, "Beitrag zur Theorie des Ferromagnetismus",
    Z. Phys. 31, 253 (1925)

[2] L. Onsager, "Crystal Statistics I",
    Phys. Rev. 65, 117 (1944)

[3] R.B. Potts, "Some Generalized Order-Disorder Transformations",
    Math. Proc. Camb. Phil. Soc. 48, 106 (1952)

[4] K. Camsari et al., "P-bits for Probabilistic Spin Logic",
    Appl. Phys. Rev. 6, 011305 (2019)


================================================================================
15. TROUBLESHOOTING
================================================================================

15.1 Common Errors
------------------

"Asymmetric coupling matrix":
    Your coupling matrix J is not symmetric.
    Solution: Ensure J[i,j] == J[j,i] for all i,j.
    Or use @directed annotation if asymmetry is intentional.

"Invalid operation for spin type":
    You're using an operation not supported by your spin type.
    Solution: Use the correct operation for your spin type.
    Example: Use delta() for Potts, not multiplication.

"Parameter constraint violated":
    A parameter violates its declared constraint.
    Solution: Check the 'where' clause and provide valid parameters.

"Problem too large for device":
    The Hamiltonian has more spins than the device supports.
    Solution: Use a device with more capacity or reduce problem size.

15.2 Performance Issues
-----------------------

Slow compilation:
    - Large systems with all-to-all coupling are expensive
    - Use sparse representations for large, sparse systems
    - Pre-compile and cache for repeated use

Slow sampling:
    - Reduce num_samples for initial testing
    - Use JAX backend for larger systems
    - Consider temperature schedule for optimization

15.3 Getting Help
-----------------

1. Check this manual and the language specification
2. Review error messages carefully - they include hints
3. Test with smaller systems first
4. Report issues at: https://github.com/dmjdxb/Thermodynamic-Computing-Platform-/issues


================================================================================
16. REFERENCE
================================================================================

16.1 Keywords
-------------

Types:        spin, coupling, field, lattice, graph, real, int, bool
Spin types:   ising, binary, potts, clock, continuous
Declarations: hamiltonian, system, param, const, let, import, from
Constructs:   sum, product, over, where, for, in, if, else
Lattice:      chain, square, triangular, honeycomb, kagome, cubic
Boundary:     periodic, open, fixed
Operators:    and, or, not, mod
Physics:      neighbors, next_neighbors, all_pairs, distance
Constraints:  require, assert, symmetric, positive, normalized

16.2 Standard Library Models
----------------------------

Model                   Description
-----                   -----------
IsingChain              1D Ising chain
Ising2D                 2D Ising on square lattice
IsingTriangular         2D Ising on triangular lattice
Potts2D                 q-state Potts on square lattice
SherringtonKirkpatrick  SK spin glass
MaxCut                  Maximum cut problem
QUBO                    Quadratic unconstrained binary optimization
Hopfield                Hopfield associative memory
RBM                     Restricted Boltzmann machine

16.3 Built-in Functions
-----------------------

Lattice:     neighbors, next_neighbors, all_pairs, sites, distance
Spin:        delta, cos, sin, dot
Math:        sqrt, abs, exp, log, sin, cos, tan, min, max

16.4 Annotations
----------------

@model          Mark as library model
@directed       Allow asymmetric couplings
@quenched       Random but fixed disorder
@sparse         Hint for sparse representation
@validate(X)    Set validation level (strict/fast/none)
@unit("X")      Attach physical unit for documentation


================================================================================
                              END OF USER MANUAL
================================================================================
