The clocked program's rules are definable #
A reduction has to write its machine down: the emitted table must be read off
the interpreted structure, which is what
DescriptiveComplexity.Draw.Data.reads_progFrom asks, and what it asks of the
rules is that each of them be first-order definable in the sense of
DescriptiveComplexity.Draw.URulesDefinable.
The clocked program shares its whole tower with the space-bounded one, so the
tower's definability (DescriptiveComplexity.Draw.Data.uRulesDefinable_varRuleF)
serves unchanged; what is new is the spine, whose checkpoints have two rules
instead of three, and the outer layer, whose sweeps are specifications
rather than kits. Both are here, and so are the program's own two
specifications: uRulesDefinable_nexProg is the whole clocked rule set, and
what a reduction still owes is its own VarArgs, the same obligation the
space-bounded one already meets.
What the file's advance computes #
The one thing a clocked program writes that is not a copy of a slot is its sweep's pointer, and what it holds after a step is the next register's own tuple. Below the last tuple of a block that is the tuple's lexicographic successor, which is what the definability of the advance is read off.
Within a block the advance is the tuple's own successor: the layout order is block-major and the tuples are ordered lexicographically, so below the last tuple the next register is the same block at the next tuple.
Dependency graph
The greatest block: the last of the layout's blocks, which is a fact about the block order alone and not about the instance.
Equations
Instances For
Dependency graph
The last register's block is that greatest block: the layout order is block-major, so the greatest index sits in the greatest block whatever the instance. This is what makes the sweep's stop test a question the formula can be built from – it compares the phase's block with a constant.
Dependency graph
The first register's tuple is the least element everywhere: the layout order is block-major and lexicographic within a block, so the least index of a block carries the least tuple. This is what the sweep's exit writes into the pointer when it resets to the file's first register.
Dependency graph
The least tuple is below every tuple: at the first differing coordinate the least element is smaller, which is what the lexicographic order asks.
Dependency graph
Above the last tuple of a block lies another block: nothing in the block is above its last tuple, so a strictly greater index has a strictly greater block.
Dependency graph
The next block, as a fact about the block order: the least block above this one, or this one if there is none.
Equations
- DescriptiveComplexity.Draw.blkNextTag K b = if h : ∃ (c : Option K), DescriptiveComplexity.WMLt (DescriptiveComplexity.Wide.blkTagLe K) b c then ⋯.choose else b
Instances For
Dependency graph
The sweep's next block is that one, so it is chosen when the formula is built and not at the instance – which is what a destination phase being a constant asks for.
Dependency graph
A roll-over resets the tuple: at the last tuple of a block that is not the last, the next register is the first of the next block, so the pointer's coordinates all become the least element.
Dependency graph
The first register's block is the blockless one: the layout puts the
registers that stand for no block first, so the least index's block is
none.
Dependency graph
The greatest tuple is the greatest element everywhere: what the sweep's roll-over test asks about the pointer, coordinate by coordinate.
Dependency graph
A tuple is the greatest exactly when every coordinate is, which is the form the roll-over test takes as a formula.
Dependency graph
The clocked spine #
The clocked evaluation's spine is definable: one checkpoint per spine position, with two rules each – the walk back to the marker, and the dispatch, which goes into the position's machinery below the last checkpoint and out of the evaluation at it. There is no third rule, the clocked evaluation running once and leaving into whatever phase its caller names.
Dependency graph
The clocked evaluation's machineries are definable: the same tower the space-bounded program runs, one copy per spine position and the output's, at the clocked program's own phases.
Dependency graph
The clocked evaluation is definable: its spine over those machineries.
Dependency graph
The file-laying sweep's own definability #
What USweepSpecDef asks of DescriptiveComplexity.Draw.Data.buildSpec, one
field at a time. The two tests are questions about the pointer's coordinates –
each is the greatest element, or the pointer is at the last register – and the
st0 reset writes the least element into them.
The roll-over test is definable: the pointer holds the last tuple exactly when every coordinate slot holds the greatest element.
Dependency graph
The stop test is definable: the pointer is at the last register exactly when its block is the last one – a comparison the formula is built with – and every coordinate slot holds the greatest element.
Dependency graph
The reset to the file's first register is definable: the coordinate slots take the least element and every other slot keeps what it held. Which slots are coordinates is decided when the formula is built.
Dependency graph
The first-register test is definable: the pointer is at the file's first register exactly when its block is the blockless one – decided when the formula is built – and every coordinate slot holds the least element.
Dependency graph
What the file-laying sweep writes is definable: the register mark and its two ends, the block one-hot, the name slots the pointer holds, the padding test, and the blank in every track the file does not carry. Every one of them is a slot of the control or a designated element, which is what makes the sweep a definable write.
Dependency graph
The pointer's next tuple is definable, coordinate by coordinate: which
coordinate rolls over is a question about which coordinates are maximal, and
the value at it is the order's own successor. This is
DescriptiveComplexity.Draw.Data.uSlotDefinable_tupNext_lvC at the sweep's
own coordinates.
Dependency graph
The sweep's advance is definable: at a coordinate slot the pointer takes the next register's own tuple – the lexicographic successor within a block, the least element at a roll-over – and every other slot keeps what it held. This is the one write of the whole program that is not a copy.
Dependency graph
The outer layer #
A clocked program's two sweeps are specifications rather than kits: what they write at a cell, where they leave the pointer, and when they are over are the caller's, so their definability is the caller's too. These are the two bundles, and everything else in the outer layer – the opening step, the approach, the two walks home and their exits, the guess's stop – is a constant rule with a guard the toolkit already has.
What makes a file-laying sweep definable: its write, its three pointers and its two tests. The next block is a function of the phase alone, so nothing is asked of it.
- wr (b : B) : UTrDefinable fun (e : Env L) => (β e).wr b
The tracks it leaves at the cell.
- st (b : B) : UStDefinable fun (e : Env L) => (β e).st b
The pointer it leaves within a block.
- st0 : UStDefinable fun (e : Env L) => (β e).st0
The pointer the exit resets to the file's first register.
- stRoll (b : B) : UStDefinable fun (e : Env L) => (β e).stRoll b
The pointer it leaves at a roll-over.
The next block is chosen when the formula is built, not at the instance.
The roll-over test.
The stop test.
Instances For
Dependency graph
And what makes a guessing sweep definable: the same, at each value it may guess.
The tracks it leaves at the cell, at this value.
The pointer it leaves, at this value.
The pointer it leaves at a roll-over.
The next block is chosen when the formula is built.
The roll-over test.
The stop test.
Instances For
Dependency graph
The file-laying sweep is definable, field by field: what it writes is the file's background at the register the pointer names, where it leaves the pointer is the next register's tuple, its exit resets to the file's first register, and its two tests ask whether the pointer is at the last tuple and at the last register. The next block is a function of the phase, so it is chosen when the formula is built.
Dependency graph
The sweep that does nothing is definable: every field is the identity or
a constant, and its two tests are True – which is what makes the phase a single
step. This is the specification a program that is handed its file puts where a
file-laying one puts uSweepSpecDef_buildSpec.
Dependency graph
What the guessing sweep writes is definable: the stage tracks take the guessed bit – a designated element, chosen when the formula is built, since the value guessed is the rule's own shape – and every other slot keeps what it held.
Dependency graph
The guessing sweep is definable: it writes the guessed bit and moves no
pointer, so every field but the write is the identity or a constant. Its stop is
not a test at all – the sweep stops nondeterministically, which is why Roll is
always true and Done never.
Dependency graph
The clocked program's outer layer is definable: the opening step that plants the two marks, the approach walk and its stop, the file-laying sweep at its specification, the walk home and its turn, the guessing sweep at its own specification and its stop, the second walk home, and the evaluation's rules as the parameter.
Dependency graph
The clocked program's whole rule set is definable: the outer layer around the evaluation, at any two sweep specifications that are themselves definable.
Dependency graph
The clocked program's own rule set is definable: the two sweeps it
actually runs, the tower it shares with the space-bounded program, and the outer
layer around them. This is what a reduction emitting the clocked machine has to
hand DescriptiveComplexity.Draw.Data.reads_progFrom; what is left to it is
its own VarArgs, which is the same obligation the space-bounded reduction
already meets.
Dependency graph
The rule set of a clocked program that is handed its file is definable,
and needs no coordinate map: the sweep that would have laid the file is
nullSpec, whose definability is free, so nothing in the program asks for an
injective Fin dd → CtlIx – which is the map no wide machine's control can hold
(DescriptiveComplexity.Draw.card_ctl_lt_card_univ). This is the rule set a
reduction into DescriptiveComplexity.WideRegAccept emits.
Dependency graph
The clocked program's accepting predicate is definable: the phase is decided when the formula is built, and the bit it conjoins is the outermost variable's verdict – the same field the space-bounded program accepts on.