Documentation

DescriptiveComplexity.Problems.Wide.DrawDefAcc

The folds are definable #

What the program's control holds between rounds is a fold: one accumulator per level of a quantifier prefix, closed by a leaf flag. Reading it back is DescriptiveComplexity.Draw.chainFrom, a recursion down the levels, and writing it at a carry is DescriptiveComplexity.Draw.Data.putVec of a family whose entries branch on the carry.

Both are definable, and for the same reason: the recursion is over a fixed number of levels, so recursing the same way builds the pattern function. The atoms are DescriptiveComplexity.Draw.Data.uGDefinable_readVec and uGDefinable_ctlBit; everything else is the connectives.

The matrix's own value at the atoms' verdicts (DescriptiveComplexity.Draw.qfValue) is the same shape one level down – a recursion over the syntax rather than over the levels – so it is here too.

The chain #

theorem DescriptiveComplexity.Draw.Data.uGDefinable_chainFrom {L : FirstOrder.Language} {dt : Data L} [Fintype dt.SlotIx] {m : } (accs : Fin mdt.CtlIx) {leaf : (e : Env L) → (dt.CtlIxe.α)(dt.SlotIxe.α)Prop} (hleaf : UGDefinable leaf) (pol : Bool) (n j : ) :
UGDefinable fun (e : Env L) (f : dt.CtlIxe.α) (g : dt.SlotIxe.α) => chainFrom pol (dt.readVec e.one accs f) (leaf e f g) n j

A fold, read back, is definable: the recursion down the levels is finite, so recursing the same way builds the formula. The leaf it closes with is the caller's – a flag of the control, or a bit it is about to store.

Dependency graph
theorem DescriptiveComplexity.Draw.Data.uGDefinable_accVerdict {L : FirstOrder.Language} {dt : Data L} [Fintype dt.SlotIx] (pol : Bool) :
UGDefinable fun (e : Env L) (f : dt.CtlIxe.α) (x : dt.SlotIxe.α) => dt.accVerdict e.one pol f

The inner fold's verdict is definable.

Dependency graph
theorem DescriptiveComplexity.Draw.Data.uGDefinable_sacVerdict {L : FirstOrder.Language} {dt : Data L} [Fintype dt.SlotIx] (pol : Bool) :
UGDefinable fun (e : Env L) (f : dt.CtlIxe.α) (x : dt.SlotIxe.α) => dt.sacVerdict e.one pol f

A sub-fold's verdict is definable.

Dependency graph

The write at a carry #

theorem DescriptiveComplexity.Draw.Data.uStDefinable_carryVec {L : FirstOrder.Language} {dt : Data L} [Fintype dt.SlotIx] {m : } {accs : Fin mdt.CtlIx} (hinj : Function.Injective accs) (leafSlot : dt.CtlIx) (pol : Bool) (n c : ) :
UStDefinable fun (e : Env L) (f : dt.CtlIxe.α) (x : dt.SlotIxe.α) => dt.putVec e.zero e.one accs f fun (j : Fin m) => if j < c then dt.readVec e.one accs f j else if j = c then if pol c = true then dt.readVec e.one accs f c chainFrom pol (dt.readVec e.one accs f) (dt.ctlBit e.one f leafSlot) n (c + 1) else dt.readVec e.one accs f c chainFrom pol (dt.readVec e.one accs f) (dt.ctlBit e.one f leafSlot) n (c + 1) else pol j = false

A fold at a tuple successor is definable: below the carry each level keeps its bit, the carry absorbs the chain below it, and the levels above it reset – three branches decided when the formula is built.

Dependency graph
theorem DescriptiveComplexity.Draw.Data.uStDefinable_carryAcc {L : FirstOrder.Language} {dt : Data L} [Fintype dt.SlotIx] (pol : Bool) (c : ) :
UStDefinable fun (e : Env L) (f : dt.CtlIxe.α) (x : dt.SlotIxe.α) => dt.carryAcc e.zero e.one pol c f

The inner fold at a carry.

Dependency graph
theorem DescriptiveComplexity.Draw.Data.uStDefinable_carrySac {L : FirstOrder.Language} {dt : Data L} [Fintype dt.SlotIx] (pol : Bool) (c : ) :
UStDefinable fun (e : Env L) (f : dt.CtlIxe.α) (x : dt.SlotIxe.α) => dt.carrySac e.zero e.one pol c f

A sub-fold at a carry.

Dependency graph
theorem DescriptiveComplexity.Draw.Data.uStDefinable_initSac {L : FirstOrder.Language} {dt : Data L} [Fintype dt.SlotIx] (pol : Bool) :
UStDefinable fun (e : Env L) (f : dt.CtlIxe.α) (x : dt.SlotIxe.α) => dt.initSac e.zero e.one pol f

A sub-fold at its first tuple.

Dependency graph
theorem DescriptiveComplexity.Draw.Data.uStDefinable_setSubLeaf {L : FirstOrder.Language} {dt : Data L} [Fintype dt.SlotIx] {b : (e : Env L) → (dt.CtlIxe.α)(dt.SlotIxe.α)Prop} (hb : UGDefinable b) :
UStDefinable fun (e : Env L) (f : dt.CtlIxe.α) (g : dt.SlotIxe.α) => dt.setSubLeaf e.zero e.one (b e f g) f

Storing a sub-fold's leaf.

Dependency graph

The atoms a leaf is evaluated from #

theorem DescriptiveComplexity.Draw.Data.uGDefinable_blkAtomHolds {L : FirstOrder.Language} {dt : Data L} [Fintype dt.SlotIx] {B : SOBlock} {n : } (v : Fin ndt.CtlIx) (κ : BlkAtom L B n) :
UGDefinable fun (e : Env L) (f : dt.CtlIxe.α) (x : dt.SlotIxe.α) => BlkAtom.holds (fun (x : B.ι) (x_1 : Fin (B.arity x)e.α) => False) (fun (j : Fin n) => f (v j)) κ

A block atom's value at the control is definable. Three of its four shapes are what a guard may now ask: two control slots are equal, one is at most another, and a relation of the source vocabulary holds of a tuple of them – the last two being exactly what an equality pattern cannot say. The fourth, a relation variable of the block, is a read leaf and never evaluated here.

Dependency graph

The matrix at its atoms' verdicts #

theorem DescriptiveComplexity.Draw.Data.uGDefinable_qfValue {L : FirstOrder.Language} {dt : Data L} [Fintype dt.SlotIx] {L' : FirstOrder.Language} {α : Type} {n : } (φ : L'.BoundedFormula α n) (val : (e : Env L) → (dt.CtlIxe.α)(dt.SlotIxe.α)L'.BoundedFormula α nProp) :
(∀ (a : L'.BoundedFormula α n), UGDefinable fun (e : Env L) (f : dt.CtlIxe.α) (g : dt.SlotIxe.α) => val e f g a)UGDefinable fun (e : Env L) (f : dt.CtlIxe.α) (g : dt.SlotIxe.α) => qfValue φ (val e f g)

A quantifier-free formula's value at a definable reading of its atoms is definable: a recursion over the syntax, the atoms being the caller's.

Dependency graph
theorem DescriptiveComplexity.Draw.Data.uGDefinable_postLeaf {L : FirstOrder.Language} {dt : Data L} [Fintype dt.SlotIx] (v : dt.VarIx) :
UGDefinable fun (e : Env L) (f : dt.CtlIxe.α) (x : dt.SlotIxe.α) => dt.postLeaf e.one v f

The matrix's value at the atoms' verdicts is definable: each atom's verdict is one of finitely many control flags.

Dependency graph