The bounded-iteration machine — proof internals #
Complexity.Cobham.iterate_mem_FP needs one machine: given a polynomial-time
G, a machine that applies G to its own input |x| times. This file builds
it out of the phase contracts of
Complexitylib.Classes.P.Cobham.Internal.IterateLayout.
Layout #
Three bookkeeping tapes (rfIdx the loop's fuel register, wfIdx the reset's
fuel register, junkIdx scratch for the register arithmetic) followed by
TM.applyTM's own block (appIdx), whose virtual input vinIdx carries the
running value and whose last tape resIdx receives each result.
Phases #
Complexity.iterTail— the five phases that follow every application: park, rewind the result, blank the scratch, move the result into virtual-input position, blank the result tape. Shared by the loop body and the setup.Complexity.iterBody— one application of the iterated function followed by the tail; this is what the loop iterates.Complexity.iterSetup— bump, load|x|into the loop register, evaluate a padding polynomial into the reset register, putpair [] xon the result tape, then the tail.Complexity.iterTM— setup, loop, and one final application whose output is the real output tape.
A confinement frame for an arbitrary bounded run #
Resetting the scratch of an opaque machine needs to know how far its heads can
have travelled. Any b-step run from tapes parked at cell 1 and blank beyond
it stays inside cell 1 + b.
Every bounded run is confined. From work tapes parked at cell 1 whose
content is confined to cell 1, a b-step run leaves every work tape inside
H and blank beyond H.
The shared tail #
Every application of the iterated function — the loop body's, and the setup's
pair [] x — leaves its result on resIdx with the scratch dirty. The five
phases below restore the entry shape TM.applyPre demands.
The tail's contract. From a result tape carrying v and a block whose
tapes are confined to 1 … H, the five phases rebuild TM.applyPre M v.
One iteration #
The loop body is one application of the iterated function followed by the tail.
One combinator seam on a tape satisfying the left-marker invariant: the
cells are untouched and the head only ever bounces off ▷.
The three bookkeeping tapes, packaged as a placement frame.
Equations
- Complexity.bookTapes rfT junkT H i = if i = Complexity.rfIdx then rfT else if i = Complexity.wfIdx then Complexity.TM.regTape H else junkT
Instances For
The loop body: apply the iterated function once, then restore the entry shape.
Equations
- Complexity.iterBody M = (Complexity.TM.placeWorkTM 3 0 M.applyTM).seqTM (Complexity.iterTail k)
Instances For
The body's contract. From the entry shape for y, the body reaches the
entry shape for G y, holding both registers and the junk tape fixed.
The loop #
TM.forRegTM drives the body once per mark of the fuel register rfIdx,
threading the iteration-indexed ghost family below.
The whole tape family at iteration i: the entry shape for the i-th
iterate on TM.applyTM's block, the two registers, and the junk tape.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The loop's contract. v applications of the iterated function, each
returning the block to its entry shape.
The setup #
Bump, load |x| into the loop register, evaluate the padding polynomial into
the reset register, and put pair [] x on the result tape.
The tape family the emission phase starts from: TM.applyTM's block blank,
the bookkeeping tapes as given.
Equations
- Complexity.emitStart extras i = if Complexity.TM.placeWorkInMiddle 3 (k + 2) i then Complexity.TM.parkedBlank else extras i
Instances For
The setup's emission phase. From the bumped input holding x and an
all-blank block, pair [] x lands on the result tape and the whole block stays
inside H.
The register value cap the padding polynomial's evaluation runs under.
Equations
- Complexity.polyM p n = ((Complexity.TM.polyCoeffs p).sum + 1) * (n + 1) ^ (Complexity.TM.polyCoeffs p).length + n + Polynomial.eval n p
Instances For
The setup machine: bump every head off cell 0, load |x| into the loop
register, evaluate the padding polynomial into the reset register, and emit
pair [] x onto the result tape.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Complexity.iterSetup's time bound.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The whole machine #
Setup, loop, and one final application whose output lands on the real output tape. Over-iteration is harmless, so that last application is just one more iteration.
The frame of the final application: the three bookkeeping tapes and the result tape, which the last application no longer needs.
Equations
Instances For
Setup, loop, and the final application.
Equations
Instances For
The main run. From the result tape carrying the initial value, the
machine iterates v + 1 times and writes the last value to the real output.
The complete iteration machine.
Equations
- Complexity.iterTM M p = (Complexity.iterSetup k p).seqTM (Complexity.iterMain M)
Instances For
Complexity.iterTM's time bound.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The iteration machine computes the iterate. On input x it applies G
to pair [] x exactly |x| + 1 times, provided the padding polynomial p
dominates the length bound r and the source machine's own bound tp.
Polynomial bounds #
Complexity.iterBound is a sum of products of polynomial evaluations, so the
closure API of Complexitylib.Asymptotics.PolyBound bounds it directly.
FP is closed under iterating a polynomial-time function once per input
bit, provided every intermediate value stays polynomially bounded.