Documentation

Complexitylib.Models.TuringMachine.SingleTape.Internal

Single-tape simulation — encoding internals #

Foundations for NTM.singleTapeSim (see docs/A4-SingleTapeSimulation.md): the binary symbol codec and the block-index arithmetic for laying k work tapes onto one. These are path-independent: any single-work-tape encoding over the fixed alphabet Γ = {0,1,□,▷} needs a binary code (so that literal can serve as the end-of-used-region sentinel) and a per-position block layout. Proof internals only — correctness of the full simulation is established downstream.

Binary symbol codec #

A writable symbol Γw = {0,1,□} is stored in two cells over {0,1} (never ), so that a literal inside the used region is impossible and can mark its end. Code: □ ↦ 00, 0 ↦ 01, 1 ↦ 10.

The writable codec agrees with the Γ-valued one under Γw.toΓ.

@[simp]

The codec round-trips.

No active code cell is : encoded symbols use only {0,1}. This is what lets a literal mark the end of the used region.

An encoded code cell is never either, so the global at cell 0 stays unique within the work tape.

The full-alphabet codec round-trips on every non- symbol.

Bridge: encoding a writable symbol agrees with the full-alphabet codec on its image. Lets δ' write via encSym while the invariant reads encSymΓ.

Both code cells are writable (≠ ▷), so encoding never introduces a second (holds even for the junk ▷ ↦ 00 case).

Neither code cell is : codes use only {0,1}, so a literal can mark the end of the used region.

Block layout #

Position-major: super-position p ≥ 1 occupies a block of blockWidth k = 3*k cells starting at blockStart k p = 1 + (p-1)*3k. Within a block, tape j uses offsets 3j, 3j+1 (symbol code) and 3j+2 (head-present bit). Cell 0 is the global .

Cells per super-position block: 2 symbol cells + 1 head bit, per tape.

Equations
Instances For

    First cell of the block for super-position p ≥ 1.

    Equations
    Instances For
      @[simp]

      The first super-position's block starts at cell 1, directly after the .

      Consecutive blocks are exactly blockWidth k apart.

      Blocks start at or after cell 1 (never the cell 0).

      theorem Complexity.NTM.SingleTape.blockStart_lt_blockStart {k : } (hk : 1 k) {p q : } (hp : 1 p) (hpq : p < q) :

      For positive width, block starts are strictly increasing in the position.

      The cell holding tape j's head-present bit within block p (offset 0 of the triple: head-bit-first, so a sweep learns "head here" before passing the symbol cells).

      Equations
      Instances For

        The first (high) symbol cell of tape j within block p (offset 1; the low symbol cell is symCell + 1 at offset 2).

        Equations
        Instances For

          Within a block, tape j's three cells stay inside [blockStart, blockStart+3k).

          theorem Complexity.NTM.SingleTape.blockStart_le (k : ) {p q : } (hpq : p q) :

          Block starts are monotone (non-strict) in the position.

          Tape j's whole triple fits strictly before the next block: headBitCell + 3 ≤ blockStart (p+1) (the +2 cell is the last of the triple).

          The simulation invariant #

          SimInvAt k t w M asserts that the single work tape t encodes the k work tapes w, with the used region materialized up to super-position M (the maximum position any head has reached). This is the relation preserved by one simulated macro-step; the two behavioural lemmas of singleTapeSim follow from base case + preservation + iteration. See docs/A4-SingleTapeSimulation.md.

          structure Complexity.NTM.SingleTape.SimInvAt (k : ) (t : Tape) (w : Fin kTape) (M : ) :

          The single tape t encodes the k work tapes w, materialized up to M.

          Instances For

            Base case. The initial single tape Tape.init [] encodes the initial k-tape configuration (all heads at 0, all blank), materialized to M = 0 (empty used region — the sentinel starts right at cell 1).

            theorem Complexity.NTM.SingleTape.SimInvAt.cells_congr {k : } {t t' : Tape} {w : Fin kTape} {M : } (h : SimInvAt k t w M) (hc : t'.cells = t.cells) :
            SimInvAt k t' w M

            SimInvAt depends on the encoding tape only through its cells (never its head), so it transfers along any cell-preserving change (e.g. a head move).

            theorem Complexity.NTM.SingleTape.SimInvAt.decSymΓ_symCell_head {k : } {t : Tape} {w : Fin kTape} {M : } (h : SimInvAt k t w M) (j : Fin k) (hp1 : 1 (w j).head) (hpM : (w j).head M) :
            decSymΓ (t.cells (symCell k (w j).head j)) (t.cells (symCell k (w j).head j + 1)) = (w j).read

            GATHER decode kernel (head off cell 0). When tape j's head is in the materialized region, decoding its two symbol cells recovers exactly the symbol under that head — what the sweep accumulates.

            theorem Complexity.NTM.SingleTape.SimInvAt.read_eq_start_of_head_eq_zero {k : } {t : Tape} {w : Fin kTape} {M : } (h : SimInvAt k t w M) (j : Fin k) (h0 : (w j).head = 0) :

            GATHER decode kernel (head on cell 0). A head at position 0 reads ; the sweep finds no marker for it and records .

            theorem Complexity.NTM.SingleTape.SimInvAt.materialized_ne_blank {k : } {t : Tape} {w : Fin kTape} {M : } (h : SimInvAt k t w M) {c : } (hc1 : 1 c) (hc2 : c < blockStart k (M + 1)) :

            No inside the materialized region. Every cell strictly between the (cell 0) and the sentinel block is a code or head-bit cell, hence in {0,1} — so the first a rightward sweep meets is exactly the sentinel at blockStart k (M+1). (Holds vacuously for k = 0.)

            theorem Complexity.NTM.SingleTape.SimInvAt.materialized_ne_start {k : } {t : Tape} {w : Fin kTape} {M : } (h : SimInvAt k t w M) {c : } (hc1 : 1 c) (hc2 : c < blockStart k (M + 1)) :

            No inside the materialized region. Every cell strictly between the (cell 0) and the sentinel block is a code or head-bit cell (in {0,1}), hence never — so uniquely marks cell 0. The REWIND sweep's precondition.