What a register file has to be #
A wide machine cannot read the digits of the address it is on, so every program for one keeps a register file: one recognizable cell per element of the instance, holding one bit of a track. The walks, the tests and the mirror ask four things of that file and nothing else:
stand on the cell of
u, write there, move to the cell of the next element, recognize the two ends.
This file says what a family of cells has to satisfy for those four to work, and the answer is short: it has to be strictly monotone, and no register may be the empty address.
The index is arbitrary. A space-bounded program's file has one register per
element and that is what DescriptiveComplexity.RegFile names, but a program
that has to lay its file out on a clock cannot afford that index – a rule sees
the control and the cell under the head and nothing else, so the only addresses
it can locate are a fixed number of tuple roll-overs from where it starts, and
the elements are more. DescriptiveComplexity.IxFile is therefore the interface
at an arbitrary ordered index, and DescriptiveComplexity.RegFile is its
diagonal case (DescriptiveComplexity.RegFile.toIx), every elementwise
statement below being the general one read there. Two linear orders are in play
in the general form and only one at the diagonal: that of the addresses,
over which the cells are compared, and that of the index, in which the
registers are laid out.
- Monotonicity gives injectivity (
DescriptiveComplexity.RegFile.injective) and the converse comparison (DescriptiveComplexity.RegFile.lt_iff), so the file is ordered exactly like the instance and a walk recovers the order and nothing else. It also gives the fact that turns a move between consecutive registers into a single scan: nothing is a register between two consecutive ones (DescriptiveComplexity.RegFile.gap), so the scan cannot overshoot or stop early. - Nonemptiness of a cell (
DescriptiveComplexity.RegFile.cell_nonempty) is what lets the head step below the first register, which is where a downward pass ends.
Two files satisfy this. The one a space-bounded program uses is the ladder the
input channel marks – DescriptiveComplexity.wmSegFile, whose cell for x is the
initial segment {y | y ≤ x} – and it is free, being in the instance before any
transition is written. It is also, as DescriptiveComplexity.Problems.Wide.Marks
explains, a geometric ruler lying in the top half of the tape, which a clocked
program cannot afford to walk twice. A clocked program therefore builds its own
file low on the tape and instantiates the same walks at it: that is what this
interface is for, and why the walks above it name a DescriptiveComplexity.RegFile
rather than DescriptiveComplexity.wmSeg.
An ordered index, its successors and its ranks #
Everything a register walk asks of a file is about the order its cells are laid out in, and nothing about what indexes them. The index of the file a space-bounded program uses is the instance itself, which is why the elementwise names below read as “per element”; a program that has to lay its file out on a clock cannot afford that index, so the general form comes first and the elementwise one is its diagonal.
The successor in an index's order: the least index strictly above one. The pointer of a register walk steps by this, in the control, while the head scans from one register to the next.
Equations
- DescriptiveComplexity.IxSucc ile u u' = (DescriptiveComplexity.WMLt ile u u' ∧ ∀ (v : I), DescriptiveComplexity.WMLt ile u v → ile u' v)
Instances For
Dependency graph
Every index but the greatest has a successor.
Dependency graph
The rank of an index: the number of indices strictly below it, which is
how many registers a walk has already crossed when its pointer reaches it. Every
budget of a register walk is a difference of two of these, exactly as every
budget of an address sweep is a difference of two
DescriptiveComplexity.wideRanks.
Equations
- DescriptiveComplexity.ixRank ile u = DescriptiveComplexity.bitRank ile (fun (x : I) => True) u
Instances For
Dependency graph
Rank increases strictly along the order.
Dependency graph
Rank is monotone along the order.
Dependency graph
The rank of an index is below the number of indices, so a walk of the file crosses fewer registers than there are of them.
Dependency graph
Rank increases by exactly one along a successor, which is what makes a difference of ranks a count of registers.
Dependency graph
The successor of an element #
The successor of an element in the instance's order: the least element
strictly above it, i.e., DescriptiveComplexity.IxSucc at the diagonal index.
Equations
Instances For
Dependency graph
The rank of an element #
The rank of an element: the number of elements strictly below it.
Instances For
Dependency graph
The rank of an element is the general rank at the diagonal index.
Dependency graph
Rank increases strictly along the order.
Dependency graph
The rank of an element is below the number of elements, so a walk of the file crosses fewer registers than there are elements.
Dependency graph
The interface, at an arbitrary index #
A file is a family of addresses indexed by something ordered, and the four things a walk asks of it are about that order alone. The index of the file a space-bounded program uses is the instance itself, which is why the interface below reads as “one cell per element”; a program that has to lay its file out on a clock cannot afford that index – it can only locate a fixed number of tuple roll-overs from where it starts, and the elements are more – so the interface is stated at an arbitrary ordered index and the elementwise one is its diagonal case.
Two linear orders are in play and they are not the same: the one of the
addresses (DescriptiveComplexity.WMLe, over which the cells are compared)
and the one of the index (which says in what order the registers are laid
out). At the diagonal they coincide, which is why the elementwise statements
below take one hypothesis where the general ones take two.
A register file over an index: one cell per index, ordered like the index, none of them the empty address.
Strict monotonicity is the whole of the interface. Everything a walk needs follows from it: the cells are distinct, they are comparable exactly as their indices are, and consecutive indices have no register between them, so one scan carries the head from each register to the next.
- cell : I → A → Prop
The address of the register of an index.
The registers are ordered like the indices that name them.
- cell_nonempty (u : I) : ∃ (x : A), self.cell u x
No register is the empty address, so the head can always step below one.
Instances For
Dependency graph
The registers are ordered exactly like the indices, so a program reading its file recovers that order and nothing else.
Dependency graph
Distinct indices have distinct registers.
Dependency graph
Consecutive indices have consecutive registers: no address strictly between the register of an index and the register of its successor is a register.
Dependency graph
The empty address is below every register, no register being empty.
Dependency graph
The registers are ordered like the indices non-strictly too.
Dependency graph
Nothing below the least register is a register, in existential form.
Dependency graph
Anything below the file is below its top register.
Dependency graph
Dependency graph
Nothing strictly below the least register is a register.
Dependency graph
A register below another is not the whole tape.
Dependency graph
The interface #
A register file: one cell per element, ordered like the elements, none of them the empty address.
Strict monotonicity is the whole of the interface. Everything a walk needs follows from it: the cells are distinct, they are comparable exactly as their elements are, and consecutive elements have no register between them, so one scan carries the head from each register to the next.
- cell : A → A → Prop
The address of the register of an element.
The registers are ordered like the elements that name them.
- cell_nonempty (u : A) : ∃ (x : A), self.cell u x
No register is the empty address, so the head can always step below one.
Instances For
Dependency graph
The elementwise file is the general one at its diagonal: index the instance, ordered by the instance's own order. Every statement below is its general form read there, the two linear orders having become one.
Instances For
Dependency graph
Dependency graph
The registers are ordered exactly like the elements, so a program reading its file recovers the order of the instance and nothing else. The direction this adds to the interface is the one that matters: a register below another comes from an element below the other's.
Dependency graph
Distinct elements have distinct registers. This is about the addresses; it says nothing about the symbols in them, which in a file marked by the input channel cannot all be distinct.
Dependency graph
Consecutive elements have consecutive registers: no address strictly between the register of an element and the register of its successor is a register. That is what makes a move between two registers one scan – the machine cannot overshoot, and nothing it passes can be mistaken for a register.
Dependency graph
The empty address is below every register, no register being empty: the head starts below its file, wherever the file sits.
Dependency graph
The registers are ordered like the elements non-strictly too: what a walk between two named registers is bounded by.
Dependency graph
Nothing below the least register is a register, in existential form: the shape a walk's junk-address side condition takes.
Dependency graph
Anything below the file is below its top register: what a walk up to the file needs of where it starts. At the input channel's ladder the top register is the whole tape and the bound is free; at a file a program builds it is not, and this is how a caller supplies it.
Dependency graph
Dependency graph
Nothing strictly below the least register is a register, so a program working under its file can never mistake its own data for one.
Dependency graph
A register below another is not the whole tape, so the head standing on it can step up.
Dependency graph
Where a file sits relative to the data #
A walk asks nothing of where the file is, but a program does: it needs to know that what it writes in its working area cannot land on a register. For the file the input channel marks that is a fact about the layout – every marked cell holds the least element, and the addresses that do not are the working area – and a program that builds its own file has to arrange the same thing by choosing where to put it. Either way it is one condition, so it is asked for once.
A register file, and the addresses a program works in: every working address lies strictly below every register, so the program's data and its registers cannot collide.
The addresses the program computes with.
They all lie below the file.
Instances For
Dependency graph
The file the input channel marks #
The register file a space-bounded program gets for free: the cell of x is the
initial segment x cuts, which is where the vocabulary's input channel writes.
The facts of DescriptiveComplexity.Problems.Wide.Marks are exactly the two
fields.
The register file of the input channel.
Reducible: a program written at an arbitrary file is read at this one by
unification, and rw matches at instances transparency, so the projection
(wmSegFile h).cell has to reduce to DescriptiveComplexity.wmSeg there.
Equations
- DescriptiveComplexity.wmSegFile h = { cell := DescriptiveComplexity.wmSeg, strictMono := ⋯, cell_nonempty := ⋯ }