Quantifier-free position tests #
The quantifier-free apparatus of the subregular program ([Cha14a],
[CJ19]): a Subregular.Term walks successor/predecessor steps from a position,
and a Subregular.QF formula is a boolean combination of label and definedness tests on such
walks. Because successor and predecessor are functions, a term reaches a bounded neighbourhood
of its position with no quantifiers — the syntactic source of strict locality. Satisfaction is
decidable, and a formula whose walks are backward with depth ≤ r reads only the r + 1
symbols ending at its position (BackBounded.realize_congr). These formulas are the guards of
logical transductions (Transduction.lean) and the term language of boolean monadic recursive
schemes (BMRS.lean).
Main definitions #
Subregular.succ?/Subregular.pred?: the next/previous position, as partial functions.Subregular.Term: walks;Term.evalreads the position a walk reaches,noneoff an edge.Term.Backward/Term.Forward/Term.pdepth: one-sided walks and how far back one reaches.Subregular.QF: label/definedness tests on walks, closed under boolean combination;QF.Realizeis decidable satisfaction;initial/finalare the derived edge tests.QF.BackBounded: every walk backward with depth≤ r.
Main results #
Term.eval_backward: a backward walk of depthjfrom positionnreads exactlyn - j.BackBounded.realize_congr: a backward-bounded formula cannot distinguish positions whose bounded left contexts agree.
Implementation notes #
The logic is monadic — one position variable, so Term.eval takes a position rather than an
assignment — since every consumer (transduction guards, BMRS) is; and there is no equality atom:
with a single position variable, two walks from one origin agree exactly when both are defined
with equal displacement, so equality tests reduce to definedness tests. It is a bespoke syntax
rather than a fragment of FirstOrder.Language: over a relational word signature,
quantifier-free formulas cannot leave their variables, so bounded-window reach requires
successor and predecessor as function symbols — but a mathlib Structure interprets function
symbols totally, whereas falling off an edge is the semantics here (defined, initial,
final).
Positions #
Successor as a partial function: the position after n, defined iff it is in range.
Equations
- Subregular.succ? w n = if n + 1 < w.length then some (n + 1) else none
Instances For
Predecessor as a partial function: the position before n, defined iff n > 0.
Equations
- Subregular.pred? w 0 = none
- Subregular.pred? w n.succ = if n < w.length then some n else none
Instances For
The successor structure depends only on the length.
The predecessor structure depends only on the length.
Walks #
Equations
- Subregular.instDecidableEqTerm.decEq Subregular.Term.var Subregular.Term.var = isTrue ⋯
- Subregular.instDecidableEqTerm.decEq Subregular.Term.var a.succ = isFalse ⋯
- Subregular.instDecidableEqTerm.decEq Subregular.Term.var a.pred = isFalse ⋯
- Subregular.instDecidableEqTerm.decEq a.succ Subregular.Term.var = isFalse ⋯
- Subregular.instDecidableEqTerm.decEq a.succ b.succ = if h : a = b then h ▸ have inst := Subregular.instDecidableEqTerm.decEq a a; isTrue ⋯ else isFalse ⋯
- Subregular.instDecidableEqTerm.decEq a.succ a_1.pred = isFalse ⋯
- Subregular.instDecidableEqTerm.decEq a.pred Subregular.Term.var = isFalse ⋯
- Subregular.instDecidableEqTerm.decEq a.pred a_1.succ = isFalse ⋯
- Subregular.instDecidableEqTerm.decEq a.pred b.pred = if h : a = b then h ▸ have inst := Subregular.instDecidableEqTerm.decEq a a; isTrue ⋯ else isFalse ⋯
Instances For
The position a term reads, walking from position n of w; none once the walk falls off
an edge.
Equations
- Subregular.Term.eval w n Subregular.Term.var = if n < w.length then some n else none
- Subregular.Term.eval w n t.succ = (Subregular.Term.eval w n t).bind (Subregular.succ? w)
- Subregular.Term.eval w n t.pred = (Subregular.Term.eval w n t).bind (Subregular.pred? w)
Instances For
Directed walks #
Equations
- Subregular.Term.var.instDecidableBackward = isTrue trivial
- t.pred.instDecidableBackward = t.instDecidableBackward
- a.succ.instDecidableBackward = isFalse not_false
Equations
- Subregular.Term.var.instDecidableForward = isTrue trivial
- t.pred.instDecidableForward = isFalse not_false
- a.succ.instDecidableForward = a.instDecidableForward
A backward term of predecessor depth j, read from an in-range position n, reads exactly
position n - j — defined iff j ≤ n.
Quantifier-free formulas #
A quantifier-free formula: a boolean combination of label and definedness tests on term walks from a single position.
- label {α : Type u_2} : α → Term → QF α
- defined {α : Type u_2} : Term → QF α
- tru {α : Type u_2} : QF α
- fls {α : Type u_2} : QF α
- neg {α : Type u_2} : QF α → QF α
- conj {α : Type u_2} : QF α → QF α → QF α
- disj {α : Type u_2} : QF α → QF α → QF α
Instances For
Satisfaction of a formula at position n of w; tests on an undefined walk are false.
Equations
- Subregular.QF.Realize w n (Subregular.QF.label a t) = (((Subregular.Term.eval w n t).bind fun (x : ℕ) => w[x]?) = some a)
- Subregular.QF.Realize w n (Subregular.QF.defined t) = (Subregular.Term.eval w n t ≠ none)
- Subregular.QF.Realize w n Subregular.QF.tru = True
- Subregular.QF.Realize w n Subregular.QF.fls = False
- Subregular.QF.Realize w n φ.neg = ¬Subregular.QF.Realize w n φ
- Subregular.QF.Realize w n (φ.conj ψ) = (Subregular.QF.Realize w n φ ∧ Subregular.QF.Realize w n ψ)
- Subregular.QF.Realize w n (φ.disj ψ) = (Subregular.QF.Realize w n φ ∨ Subregular.QF.Realize w n ψ)
Instances For
Equations
- Subregular.QF.instDecidableRealize w n (Subregular.QF.label a t) = Subregular.QF.instDecidableRealize._aux_1 w n a t
- Subregular.QF.instDecidableRealize w n (Subregular.QF.defined t) = Subregular.QF.instDecidableRealize._aux_3 w n t
- Subregular.QF.instDecidableRealize w n Subregular.QF.tru = isTrue trivial
- Subregular.QF.instDecidableRealize w n Subregular.QF.fls = isFalse not_false
- Subregular.QF.instDecidableRealize w n φ.neg = instDecidableNot
- Subregular.QF.instDecidableRealize w n (φ.conj ψ) = instDecidableAnd
- Subregular.QF.instDecidableRealize w n (φ.disj ψ) = instDecidableOr
t reads an initial position: in-domain with no predecessor.
Equations
Instances For
t reads a final position: in-domain with no successor.
Equations
Instances For
Backward-bounded formulas read only a left window #
A formula is backward-bounded by r if every term it uses is backward with predecessor
depth ≤ r, so it reads only the r + 1 positions ending at its own.
Equations
- Subregular.QF.BackBounded r (Subregular.QF.label a t) = (t.Backward ∧ t.pdepth ≤ r)
- Subregular.QF.BackBounded r (Subregular.QF.defined t) = (t.Backward ∧ t.pdepth ≤ r)
- Subregular.QF.BackBounded r Subregular.QF.tru = True
- Subregular.QF.BackBounded r Subregular.QF.fls = True
- Subregular.QF.BackBounded r φ.neg = Subregular.QF.BackBounded r φ
- Subregular.QF.BackBounded r (φ.conj ψ) = (Subregular.QF.BackBounded r φ ∧ Subregular.QF.BackBounded r ψ)
- Subregular.QF.BackBounded r (φ.disj ψ) = (Subregular.QF.BackBounded r φ ∧ Subregular.QF.BackBounded r ψ)
Instances For
A backward-bounded formula reads only the r + 1 symbols ending at its position: it has the
same truth value at (w, n) and (w', n') whenever their bounded left contexts — the labels at
offsets 0 … r, and which of those offsets stay in range — agree.
Worked example #
Equations
- Subregular.instDecidableEqSym x✝ y✝ = if h : Subregular.Sym.ctorIdx✝ x✝ = Subregular.Sym.ctorIdx✝ y✝ then isTrue ⋯ else isFalse ⋯