Walking the register file #
The phase a wide machine spends its life in. Its register file is one
recognizable cell per element of the instance (DescriptiveComplexity.RegFile),
and every register operation – read a bit, flip one, increment a mirror, compare
two – is the same walk:
stand on the cell of
u, write there, and scan right to the cell of the next element; repeat until the file is exhausted.
DescriptiveComplexity.RegFile.reachesIn_regStep is one such move and
DescriptiveComplexity.RegFile.reachesIn_regWalk is the whole traversal, the
latter being the only induction a program has to be given: the machine's state
and its tape are handed over as functions of the element the pointer has
reached, and what is discharged is a single move between an element and its
successor.
Both come in the other direction too
(DescriptiveComplexity.RegFile.reachesIn_regStepBack,
DescriptiveComplexity.RegFile.reachesIn_regWalkBack), and that reading is not a
convenience: the least significant digit of an address is the WMLe-greatest
element, so a program incrementing its mirror – clear the trailing digits, set
the first that is clear – walks the file from its last register towards its
first.
Getting to a register in the first place – the last one, to begin a downward
pass, and the first one, to come back from it – is
DescriptiveComplexity.RegFile.reachesIn_toReg and
DescriptiveComplexity.RegFile.reachesIn_toRegBack: one scan each, stopped by a
symbol the target register carries and the others do not. Only the two ends of
the file need such a symbol; in a file the input channel marks, those in between
are all the same one, and must be, since a symbol is an element and there are as
many registers as elements.
Two facts make a move between consecutive registers a single scan rather than a
search: consecutive elements have no register between them
(DescriptiveComplexity.RegFile.gap), so the scan cannot overshoot or stop
early; and the pointer lives in the machine's control, where a state may hold
an element of the instance, so no address arithmetic is involved in knowing which
register one is on.
What a walk costs #
Each statement comes in a budgeted form and an erased one. A move between consecutive registers costs exactly the addresses lying between them, and a walk of a stretch of the file costs the registers it crosses times whatever bound the caller puts on one move. Which form a program uses is the whole difference between the space-bounded wide problems and the clocked one: the file the input channel marks is a geometric ruler in the top half of the tape, so walking it is affordable only when nothing is counting.
Every statement is also given at DescriptiveComplexity.wmSeg, so that a program
written against the file of the input channel names no
DescriptiveComplexity.RegFile at all.
What indexes the registers is a parameter. Every proof here is about the
order the cells are laid out in and about nothing else, so each statement is
made at a DescriptiveComplexity.IxFile – a file over an arbitrary ordered
index – and the elementwise form is its diagonal
(DescriptiveComplexity.RegFile.toIx), one line each. The pointer is a function
of the index and the states stay elements of the instance, which is what makes
the generalization free: a walk never holds an index anywhere the machine can
see, only its caller does. Two linear orders separate in the general form – the
addresses' and the index's – and a statement that needs only one says so.
What a track shows at a cell: its digit, if the cell is some element's register; nothing at any other cell. A program's tape is a function of this and of the address, and of nothing else about the track.
Stated at the cells rather than at a DescriptiveComplexity.RegFile, because a
program's tape is a definition and a file carries proofs: threading the whole
record through the definitions would make them depend on the linearity of the
order, which nothing about them does. The file appears in the theorems below,
where the proofs are wanted.
Equations
- DescriptiveComplexity.bitAtOf cell m r = ∃ (u : I), r = cell u ∧ m u
Instances For
Dependency graph
At a cell that is nobody's register a track shows nothing.
Dependency graph
The coherence condition of the passes, discharged. Two tracks agreeing off one element show the same thing at every cell but that element's register – whatever else the program keeps in its symbols, since they enter the tape only through this.
A caller finishes with congrArg: its tape is some g r (bitAtOf cell m r), and
this says the second argument does not move.
Dependency graph
One move of the walk #
One move of a register walk. In the state q, on the cell of u, the
machine writes there and moves right; then, in the state q', it scans over the
cells that are nobody's register; it arrives on the cell of the successor of u,
having spent exactly the addresses lying between the two registers.
The write is described the way every write in this development is – by naming the
new symbol assignment f' and saying it agrees with f off the cell of u – and
the scan is asked for only at the cells that are nobody's register, which is
exactly where DescriptiveComplexity.RegFile.gap says the machine will pass.
Dependency graph
One move of a register walk, the budget forgotten.
Dependency graph
The whole traversal #
A register walk. Give the machine's state and its tape as functions of
the element its pointer has reached, discharge one move of at most w steps
between each element of a stretch and its successor, and the machine walks the
whole stretch, paying w per register crossed.
This is the only induction a program is given about its register file: with it, a phase is described by what it does at one register, and the traversal never appears again.
Dependency graph
A register walk, the budget forgotten: each move is a run of any length whatever.
Dependency graph
Reaching a named register #
Before a pass can start, and between one pass and the next, the head has to get to a particular register – the last one to begin a downward pass, the first one to come back from it, or the one a pointer in the control names. Each is a scan whose stopping symbol is the name the register carries, and the two facts that make it one scan are that the registers are ordered like their elements and that a register's symbol names it.
Walking up to a distinguished register. From any cell at or below the
register of u, in a fixed state, the machine scans right to it. The caller
offers the scanning transition at the cells that are nobody's register and at the
registers of the other elements – which in a file marked by the input channel
all hold the one generic mark, so that is a single transition – and withholds it
at the symbol the register of u carries, which is what stops the scan.
Dependency graph
Walking up to a distinguished register, the budget forgotten.
Dependency graph
Walking back down to a named register, the same reading downwards: from
any cell at or above the register of u, the machine scans left to it.
Dependency graph
Walking back down to a named register, the budget forgotten.
Dependency graph
Walking the file the other way #
The least significant digit of an address is the WMLe-greatest element
(DescriptiveComplexity.Problems.Wide.Increment), so a program incrementing its
mirror propagates the carry from the last register towards the first: the walk it
does is this one.
One move of a register walk, downwards. In the state q, on the cell of
u', the machine writes there and moves left; then it scans left over the cells
that are nobody's register and arrives on the cell of the element u'
succeeds.
Dependency graph
One move of a register walk, downwards, the budget forgotten.
Dependency graph
A register walk, downwards: the mirror of
DescriptiveComplexity.RegFile.reachesIn_regWalk, from the top of a stretch of
the file to any element of it. This is the shape of a mirror increment – clear the
trailing digits, set the first that is clear – so it is the walk a program does
most.
Dependency graph
A register walk, downwards, the budget forgotten.
Dependency graph
A track over the register file #
The passes of DescriptiveComplexity.Problems.Wide.Mirror and
DescriptiveComplexity.Problems.Wide.Test take the tape as a function of one
track, tapeOf m, and each asks for the same coherence condition: changing the
track at one element changes the tape at that element's cell and nowhere else. A
program does not verify that by hand. It builds its tape by reading the track
through DescriptiveComplexity.RegFile.bitAt – the track's digit at a register
cell, nothing anywhere else – and
DescriptiveComplexity.RegFile.bitAt_congr is the condition, discharged once for
every program and every alphabet.
What a track shows at a cell of a given file.
Equations
- F.bitAt m r = DescriptiveComplexity.bitAtOf F.cell m r
Instances For
Dependency graph
Dependency graph
At a cell that is nobody's register a track shows nothing.
Dependency graph
The coherence condition of the passes, discharged. Two tracks agreeing off one element show the same thing at every cell but that element's register – whatever else the program keeps in its symbols, since they enter the tape only through this.
A caller finishes with congrArg: its tape is some g r (F.bitAt m r), and this
says the second argument does not move.
Dependency graph
One move of the walk #
One move of a register walk. In the state q, on the cell of u, the
machine writes there and moves right; then, in the state q', it scans over the
cells that are nobody's register; it arrives on the cell of the successor of u,
having spent exactly the addresses lying between the two registers.
The write is described the way every write in this development is – by naming the
new symbol assignment f' and saying it agrees with f off the cell of u – and
the scan is asked for only at the cells that are nobody's register, which is
exactly where DescriptiveComplexity.RegFile.gap says the machine will pass.
Dependency graph
One move of a register walk, the budget forgotten.
Dependency graph
The whole traversal #
A register walk. Give the machine's state and its tape as functions of
the element its pointer has reached, discharge one move of at most w steps
between each element of a stretch and its successor, and the machine walks the
whole stretch, paying w per register crossed.
This is the only induction a program is given about its register file: with it, a phase is described by what it does at one register, and the traversal never appears again.
Dependency graph
A register walk, the budget forgotten: each move is a run of any length whatever.
Dependency graph
Reaching a named register #
Before a pass can start, and between one pass and the next, the head has to get to a particular register – the last one to begin a downward pass, the first one to come back from it, or the one a pointer in the control names. Each is a scan whose stopping symbol is the name the register carries, and the two facts that make it one scan are that the registers are ordered like their elements and that a register's symbol names it.
Walking up to a distinguished register. From any cell at or below the
register of u, in a fixed state, the machine scans right to it. The caller
offers the scanning transition at the cells that are nobody's register and at the
registers of the other elements – which in a file marked by the input channel
all hold the one generic mark, so that is a single transition – and withholds it
at the symbol the register of u carries, which is what stops the scan.
Dependency graph
Walking up to a distinguished register, the budget forgotten.
Dependency graph
Walking back down to a named register, the same reading downwards: from
any cell at or above the register of u, the machine scans left to it.
Dependency graph
Walking back down to a named register, the budget forgotten.
Dependency graph
Walking the file the other way #
The least significant digit of an address is the WMLe-greatest element
(DescriptiveComplexity.Problems.Wide.Increment), so a program incrementing its
mirror propagates the carry from the last register towards the first: the walk it
does is this one.
One move of a register walk, downwards. In the state q, on the cell of
u', the machine writes there and moves left; then it scans left over the cells
that are nobody's register and arrives on the cell of the element u'
succeeds.
Dependency graph
One move of a register walk, downwards, the budget forgotten.
Dependency graph
A register walk, downwards: the mirror of
DescriptiveComplexity.RegFile.reachesIn_regWalk, from the top of a stretch of
the file to any element of it. This is the shape of a mirror increment – clear the
trailing digits, set the first that is clear – so it is the walk a program does
most.
Dependency graph
A register walk, downwards, the budget forgotten.
Dependency graph
A track over the register file #
The passes of DescriptiveComplexity.Problems.Wide.Mirror and
DescriptiveComplexity.Problems.Wide.Test take the tape as a function of one
track, tapeOf m, and each asks for the same coherence condition: changing the
track at one element changes the tape at that element's cell and nowhere else. A
program does not verify that by hand. It builds its tape by reading the track
through DescriptiveComplexity.RegFile.bitAt – the track's digit at a register
cell, nothing anywhere else – and
DescriptiveComplexity.RegFile.bitAt_congr is the condition, discharged once for
every program and every alphabet.
What a track shows at a cell of a given file.
Instances For
Dependency graph
Dependency graph
At a cell that is nobody's register a track shows nothing.
Dependency graph
The coherence condition of the passes, discharged. Two tracks agreeing off one element show the same thing at every cell but that element's register – whatever else the program keeps in its symbols, since they enter the tape only through this.
A caller finishes with congrArg: its tape is some g r (F.bitAt m r), and this
says the second argument does not move.
Dependency graph
The same, at the file the input channel marks #
Every statement above, read at DescriptiveComplexity.wmSegFile: this is the
register file a space-bounded program uses, and these are the names its phases
cite.
One move of a register walk over the file the input channel marks.
Dependency graph
A register walk over the file the input channel marks.
Dependency graph
Walking up to a distinguished register of the file the input channel marks.
Dependency graph
Walking back down to a named register of the file the input channel marks.
Dependency graph
One move of a register walk, downwards, over the file the input channel marks.
Dependency graph
A register walk, downwards, over the file the input channel marks.
Dependency graph
What a track shows at a cell of the file the input channel marks.
Equations
Instances For
Dependency graph
Dependency graph
The coherence condition of the three passes, discharged, at the file the input channel marks.
Dependency graph
The accumulator of a downward pass #
A pass down the register file carries one bit of information in its control:
whether everything it has seen so far behaved. Since it walks downwards, “so far”
is “at every register above the one it is on”, and the two states of the pass are
therefore a function of the suffix. Both subroutines built on the walk – the
mirror increment (DescriptiveComplexity.Problems.Wide.Mirror) and the file
tests (DescriptiveComplexity.Problems.Wide.Test) – are that shape, so it is
settled here.
The state a downward pass is in on arriving at the register of w: the
first state exactly when the property holds at every register strictly above.
Equations
- DescriptiveComplexity.accState ile P qy qn w = if ∀ (v : I), DescriptiveComplexity.WMLt ile w v → P v then qy else qn
Instances For
Dependency graph
The state a downward pass is in on leaving the register of w: the same
with w itself taken into account.
Equations
- DescriptiveComplexity.accStateAfter ile P qy qn w = if ∀ (v : I), ile w v → P v then qy else qn
Instances For
Dependency graph
Leaving one register is arriving at the next one down.
Dependency graph
At the last register nothing has been seen yet, so the pass starts in the first state.
Dependency graph
A pass is in one of its two states, whatever it has seen.
Dependency graph
A pass that saw a failure ends in the second state.
Dependency graph
A pass that saw no failure ends in the first state.