Documentation

Complexitylib.Classes.Containments.Internal.PHPrologue

The enumerator's prologue #

⚠️ Unreviewed by Bolton

Before the loop can start, three tapes have to be filled: a copy of the real input, for the pair emitter to read; the horizon the counter is compared against; and the unary register that drives each pass's wipe.

TM.copyInputToWorkTM's own contract says nothing about the tapes it does not write, and it is used here beside a dozen that must survive. It does not disturb them: every tape but its target is written blank and moved by TM.idleDir, so a blank tape comes back blank — which is what the frame below records, by induction along the run.

Main results #

An idled blank tape is unchanged. Writing a blank under the head of a blank tape changes nothing, and TM.idleDir does not move a head that is off the marker.

theorem Complexity.PolyExists.copyStep_blank {n : } (idx : Fin n) {c c' : Cfg n (TM.copyInputToWorkTM idx).Q} (hstep : (TM.copyInputToWorkTM idx).step c = some c') (i : Fin n) (hi : i idx) (h : c.work i = TM.blankTape) :

One step of the copier leaves a blank tape blank.

theorem Complexity.PolyExists.copyInputToWorkTM_blank_frame {n : } (idx : Fin n) {t : } {c c' : Cfg n (TM.copyInputToWorkTM idx).Q} :
(TM.copyInputToWorkTM idx).reachesIn t c c'∀ (i : Fin n), i idxc.work i = TM.blankTapec'.work i = TM.blankTape

The copier leaves every other blank tape blank, which is the frame its own contract does not record.

One step of the copier leaves the real output blank, for the same reason.

The blank tape carries the empty binary prefix.

theorem Complexity.PolyExists.copyX_hoareTime (k : ) (x : List Bool) :
(TM.copyInputToWorkTM (xIdx k)).HoareTime (fun (inp : Tape) (work : Fin (enumTapes k)Tape) (out : Tape) => inp = strTape x (work = fun (x : Fin (enumTapes k)) => TM.blankTape) out = TM.blankTape) (fun (inp : Tape) (work : Fin (enumTapes k)Tape) (out : Tape) => inp.cells = (strTape x).cells inp.head = x.length + 1 (∀ (i : Fin (enumTapes k)), i xIdx kwork i = TM.blankTape) (work (xIdx k)).HasBinaryPrefix x (work (xIdx k)).cells 0 = Γ.start out = TM.blankTape) (x.length + 1)

The input copy, contracted with its frame.

The register subroutines state their contracts with an output accumulator; with nothing emitted that is just the blank tape.

theorem Complexity.PolyExists.hoareTime_emit_of_pinned {m : } {tm : TM m} {inp₀ : Tape} {W W' : Fin mTape} {b : } (h : tm.HoareTime (fun (inp : Tape) (work : Fin mTape) (out : Tape) => inp = inp₀ work = W out = TM.blankTape) (fun (inp : Tape) (work : Fin mTape) (out : Tape) => inp = inp₀ work = W' out = TM.blankTape) b) :
tm.HoareTime (TM.EmitPred inp₀ W []) (TM.EmitPred inp₀ W' []) b

A pinned contract with a blank output is an emit contract with nothing emitted.

A unary register of T ones is the binary numeral 2 ^ T - 1. The two encodings agree cell for cell, which is what lets the prologue produce the horizon without a doubling loop.

A unary register holding zero is the blank tape.

And so is a counter tape holding zero.

The enumerator's prologue. Measure the input, evaluate the horizon's exponent and the wipe height on unary registers, bump the exponent — a register of m + 1 ones is the binary numeral 2 ^ (m + 1) - 1 — and clear the scratch.

Equations
  • One or more equations did not get rendered due to their size.
Instances For

    The bank the copy stage leaves: the input on its tape, everything else blank.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For

      The cap the Horner evaluation stays under.

      Equations
      Instances For

        The prologue's per-stage budget.

        Equations
        • One or more equations did not get rendered due to their size.
        Instances For

          The prologue's running time.

          Equations
          Instances For
            theorem Complexity.PolyExists.prologueTM_hoareTime (k : ) (p q : Polynomial ) (x : List Bool) :
            (prologueTM k p q).HoareTime (fun (inp : Tape) (work : Fin (enumTapes k)Tape) (out : Tape) => inp = strTape x work = copiedBank k x out = TM.blankTape) (fun (inp : Tape) (work : Fin (enumTapes k)Tape) (out : Tape) => inp = strTape x work = enumBank k x (2 ^ (Polynomial.eval x.length p + 1) - 1) (Polynomial.eval x.length q) 0 0 0 out = TM.blankTape) (prologueTime p q x.length)

            The prologue's contract. From the bank the copy stage leaves it lands on the loop's starting bank: the horizon on PolyExists.nIdx, the wipe height on PolyExists.regIdx, the input copy where the emitter reads it, and everything else blank.