Incrementing the mirror #
The first real subroutine of a wide machine, and the one every address
computation goes through. A program keeps a mirror of the address it is
working on – one bit per element, in a track over its register file
(DescriptiveComplexity.IxFile) – because the head cannot read the digits of its
own address. Moving the working cell one to the right means adding one to the
mirror, and adding one is:
walk the register file downwards, clearing the digits that are set; at the first digit that is clear, set it and stop clearing.
That is the binary increment of DescriptiveComplexity.Problems.Wide.Increment,
whose least significant digit is the WMLe-greatest element – which is why the
walk runs downwards – and DescriptiveComplexity.IxFile.reachesIn_mirrorIncr
says the program computes it: from the last register in the carrying state with
the mirror at s, the machine arrives below the first register in the stopped
state with the mirror at t, for the unique t with WMIncr WMLe s t. It costs
one move per register plus the step off the file, so a caller that is counting
bounds the moves and gets the product.
What a caller supplies #
The tape is given as a function of the mirror, tapeOf m, with one coherence
condition: changing the mirror at one element changes the tape at that element's
cell and nowhere else. Everything else a program keeps on its tape is therefore
carried along untouched, and no track discipline has to be fixed here. Three
transition families do the work – clear a set digit and keep carrying, set a
clear digit and stop, rewrite anything once stopped – plus the scanning
transitions that carry the head between consecutive registers.
The states are the caller's: qc for carrying, and a family qd for stopped.
The family is the point – the machine ends in qd u₀ where u₀ is the carry
position, the digit the increment set, and the conclusion says so along with its
characterization. A state may hold an element, so reporting the carry costs
nothing in the control, and it is what the fold of
DescriptiveComplexity.Problems.Wide.Fold needs: which block rolled over decides
which accumulators reset. So the caller reads both “the increment is finished” and
“here is where it carried” off the state, and neither off the tape.
The other writing pass #
DescriptiveComplexity.IxFile.reachesIn_fileWrite is the same walk with nothing
accumulated: one state throughout, and every register simply given its new digit.
Copying the mirror into a spare register, clearing a track and loading a computed
value are all that pass. Together with the read-only pass of
DescriptiveComplexity.Problems.Wide.Test these are the three shapes a program's
register work comes in – write with an accumulator, write without one, read with
one – and nothing below them is ever a case split again.
The mirror during the walk #
What the increment does to a digit #
Processing one register #
The whole case analysis of the subroutine happens here, once: what the machine
does at the register of w depends only on whether every digit above w is set
and on whether the digit at w is. Everything after this is bookkeeping, and
none of it is a case split.
The subroutine #
The mirror increment. From the last register of the file, carrying, with
the mirror at s, the machine walks down the file and arrives just below the
first register, stopped, with the mirror at the increment of s.
The three transition families do the arithmetic and the scanning ones carry the
head between consecutive registers; the coherence condition hcoh is what says
the rest of the tape – whatever else the program keeps there – comes through
untouched. The cost is one move per register, each bounded by w, plus the step
off the file.
Dependency graph
The mirror increment, the budget forgotten.
Dependency graph
Overwriting a track #
The same walk with nothing accumulated: the state never changes, and every register is simply given its new digit. Copying the mirror into a spare register, clearing a track and loading a computed value are all this pass.
Overwriting a track. A pass down the file in a single state, replacing the
track's digit at every register: the machine starts at the last register with the
track at s and arrives just below the first register with it at t.
Since nothing is accumulated, t is arbitrary – the caller's transitions say what
to write at each register, and may read the old digit to decide.
Dependency graph
Overwriting a track, the budget forgotten.
Dependency graph
The same, at the file the input channel marks #
The mirror increment over the file the input channel marks.
Dependency graph
Overwriting a track of the file the input channel marks.