The transition table, and the two promises it has to keep #
The instance a hardness reduction into DescriptiveComplexity.DWideAcceptSpace
emits is a wide machine, and a wide machine is eleven relations on a finite type
(DescriptiveComplexity.Problems.Wide.Instance reads the smallest one). This
file says what those eleven relations are, once and for all, in terms of a
table: the program's rules, each with its guard, its two phases, the symbol
it reads and the one it writes, and the direction it moves in.
What a rule is, and why it lives in the tag #
DescriptiveComplexity.Draw.Table is indexed by two arbitrary types – R, the
rules, and P, the phases – which are the two halves of
DescriptiveComplexity.Draw.Tag. A transition is therefore an element
(ctrl r, pad w): its rule is its tag and its tuple carries only the rule's
data, the elements the rule acts at. That is the library's “index rules by
attribute values, not by the transition” read at the level of the layout, and it
is what will make every defining formula of the interpretation a decision taken
when the formula is built – the source phase, the destination phase and the
direction of a rule are functions of its tag alone.
Semantics first #
Nothing here is a formula. The eleven relations are plain predicates on the
tagged-tuple universe, and the instance is only assumed to read them
(DescriptiveComplexity.Draw.Table.Reads); the interpretation that makes the
assumption true is written later, and the equivalence is definitional, the
interpreted universe being the tagged tuples themselves. Everything a program
proves is therefore proved once, about any structure reading the table.
What the file delivers #
| for | theorem |
|---|---|
| a rule fires, moving right | DescriptiveComplexity.Draw.Table.fire_right |
| a rule fires, moving left | DescriptiveComplexity.Draw.Table.fire_left |
the promise of WideAcceptSpace | DescriptiveComplexity.Draw.Table.wellFormed |
the promise DWideAcceptSpace adds | DescriptiveComplexity.Draw.Table.deterministic |
The two promises cost exactly what the layout was designed to make them cost.
Well-formedness is the order being linear – it is
DescriptiveComplexity.tagTupleLe, so DescriptiveComplexity.Wide.isLinOrd_tagTupleLe
settles it – plus the input and the blank being functional, which they are
because both are written as equations. Determinism is one condition on the
table, DescriptiveComplexity.Draw.Table.Sep: two guarded rules agreeing on the
state they apply in and the symbol they read are the same rule with the same
data. The padding of DescriptiveComplexity.Draw.pad is what makes that a
condition about payloads rather than about tuples, which is the whole reason it
is there.
The universe the reduction emits: tagged tuples, one block per tag. An
abbrev, so that it is literally the interpreted universe and a pair may be
destructured without ceremony.
Equations
- DescriptiveComplexity.Draw.Univ A R P K dd = (DescriptiveComplexity.Draw.Tag R P K × (Fin dd → A))
Instances For
Dependency graph
The transition table of the emitted machine. The reduction chooses the two designated elements of the alphabet, the payload width, and – rule by rule – a guard, the two phases, the two payloads of the state, the two payloads of the symbol, and the direction.
The three remaining fields are the machine's constants: its start state, its
accepting states, its blank, and the symbol the input channel writes in the cell
of each element (the register file of
DescriptiveComplexity.Problems.Wide.Marks).
- zero : A
The designated element a track holds when its bit is clear.
- one : A
The designated element a track holds when its bit is set.
The two designated elements differ: what a track is read back by.
The payload fits in the tuples of the universe.
Which data make the rule a transition.
- srcPh : R → P
The phase a rule applies in.
- dstPh : R → P
The phase a rule moves to.
The pointer of the state a rule applies in.
The pointer of the state a rule moves to.
The tracks of the symbol a rule reads.
The tracks of the symbol a rule writes.
- moveRight : R → Prop
Whether a rule moves the head right.
- startPh : P
The phase of the start state.
- startPl : Fin c → A
The pointer of the start state.
Which states accept.
- blankPl : Fin c → A
The tracks of the blank.
The tracks of the symbol the input channel writes in the cell of an element.
Which elements the channel writes for. Every one of them by default, which is what
DescriptiveComplexity.WideAccept's channel does; a program emitted into the register channel ofDescriptiveComplexity.WideRegAcceptrestricts it, and the elements it leaves out have no register in the file the channel hands over.
Instances For
Dependency graph
The eleven relations, as predicates #
Being a transition: a ctrl-tagged element, canonically padded, whose
data the rule of its tag admits. The padding is what gives a transition one
spelling, and so the machine its determinism.
Equations
- T.IsTr τ = match τ.1 with | DescriptiveComplexity.Draw.Tag.ctrl r => DescriptiveComplexity.Draw.IsPad c T.zero τ.2 ∧ T.guard r (DescriptiveComplexity.Draw.unpad ⋯ τ.2) | x => False
Instances For
Dependency graph
The state a transition applies in, read off its rule and its data.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The symbol a transition reads.
Equations
- T.Read τ a = match τ.1 with | DescriptiveComplexity.Draw.Tag.ctrl r => a = DescriptiveComplexity.Draw.symElt T.zero (T.readPl r (DescriptiveComplexity.Draw.unpad ⋯ τ.2)) | x => False
Instances For
Dependency graph
The state a transition moves to.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The symbol a transition writes.
Equations
- T.Write τ a = match τ.1 with | DescriptiveComplexity.Draw.Tag.ctrl r => a = DescriptiveComplexity.Draw.symElt T.zero (T.writePl r (DescriptiveComplexity.Draw.unpad ⋯ τ.2)) | x => False
Instances For
Dependency graph
Moving right: a function of the rule alone, hence of the tag.
Equations
- T.IsRight τ = match τ.1 with | DescriptiveComplexity.Draw.Tag.ctrl r => T.moveRight r | x => False
Instances For
Dependency graph
The start state.
Instances For
Dependency graph
The accepting states: a phase-tagged, canonically padded element whose
phase and pointer the table accepts.
Equations
- T.IsAcc q = match q.1 with | DescriptiveComplexity.Draw.Tag.phase p => DescriptiveComplexity.Draw.IsPad c T.zero q.2 ∧ T.accept p (DescriptiveComplexity.Draw.unpad ⋯ q.2) | x => False
Instances For
Dependency graph
The blank.
Instances For
Dependency graph
The input channel: the cell of an element the table writes for holds the mark the table gives it. Functional outright, and total exactly on the elements the table marks.
Instances For
Dependency graph
What a rule does #
The five attributes of a transition, read at the element the rule and its data
name. Each is the definitional unfolding of the predicate above with
DescriptiveComplexity.Draw.unpad_pad applied to the payload, and together they
are the only thing a program ever needs about the table.
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
Dependency graph
An instance that reads the table #
An instance reads the table: its eleven relations are the predicates above and its order is the definable one. Everything a program proves is proved under this hypothesis, so the interpretation that emits the instance has exactly eleven obligations and no more.
The order is the block-major one on tagged tuples.
The transitions.
The start state.
The accepting states.
The blank.
The direction.
The state a transition applies in.
The symbol a transition reads.
The state a transition moves to.
The symbol a transition writes.
The input channel.
Instances For
Dependency graph
Firing a rule #
The shape every subroutine of the address layer asks for – a transition with its six attributes, the direction being the one the caller wants. A program's whole interaction with the table is these two theorems.
A rule fires, moving right.
Dependency graph
A rule fires, moving left.
Dependency graph
The two promises #
The order of the emitted instance is linear, being the definable order on tagged tuples.
Dependency graph
The emitted instance is well formed. Three conditions
(DescriptiveComplexity.wideData_wellFormed_iff), and all three are settled by
the layout: the order is DescriptiveComplexity.tagTupleLe, and the input and
the blank are equations.
Dependency graph
The separation condition: two guarded rules that apply in the same state and read the same symbol are the same rule with the same data. This is the whole content of determinism, and the only obligation a concrete table has to discharge by hand.
Equations
Instances For
Dependency graph
The separation condition, asked at some phases only: two guarded rules
that apply in the same state and read the same symbol are the same rule with the
same data, provided the phase they apply in is one Ph names.
A program that guesses does not separate everywhere – that is what guessing is –
but it separates at every phase it can be in once the guess is over, and
DescriptiveComplexity.TMData.uniqueFrom_of_invariant asks for no more.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dependency graph
The transition is pinned wherever the phases separate: at a state whose
phase satisfies Ph, the state and the symbol read name the transition. This is
the hypothesis of DescriptiveComplexity.TMData.step_functional_at, and with it
a guessing program is functional off its guess.
Dependency graph
A transition has one destination: it is an equation in the rule.
Dependency graph
A transition writes one symbol: it is an equation in the rule.
Dependency graph
The emitted instance is deterministic, given the separation condition.
The three other clauses of DescriptiveComplexity.WideDet are free: the start
state, the destination and the written symbol are all written as equations.
Dependency graph
The bounds of the outer loop #
DescriptiveComplexity.Draw.wmSetLe_logicalTop is about the block-major order on
tagged tuples; a program's loop is about the order its instance carries. They are
the same order, which is what the layout was chosen for, and this is where the two
are joined.
The order on addresses depends on the order of the elements only through its extension.
Dependency graph
A logical address is at or below the last one, in the machine's own order:
the addresses whose non-argument blocks are empty – the ones that hold the stage of
the fixed point – are an initial interval of the tape, and this is the upper bound
DescriptiveComplexity.reaches_of_wideRounds is given.
Dependency graph
The two ends of a run #
What a program starts from and what it has to reach, in the table's own terms.
Between them and DescriptiveComplexity.Draw.Table.fire_right /
DescriptiveComplexity.Draw.Table.fire_left, a program never mentions
FirstOrder.Language.wide again.
The initial configuration of the emitted machine: the start state, the head on the empty address, the mark of each element in that element's cell and the blank everywhere else.
Dependency graph
The emitted machine accepts in bounded space: it starts as
DescriptiveComplexity.Draw.Table.isInit says, roams, and ends in a state the
table accepts.
Dependency graph
The emitted machine accepts on the clock: it starts as
DescriptiveComplexity.Draw.Table.isInit says, runs for fewer steps than there
are addresses – 2 ^ n of them, n the size of the drawn universe – and ends in
a state the table accepts. This is the reading a time-bounded reduction needs,
where DescriptiveComplexity.Draw.Table.acceptsSpace is the space-bounded one.