Side dependence for string functions #
A lattice of side-dependence predicates over List.DependsOn: BoundedDependence f s says a
single margin caps the influence of side s at every output coordinate,
TwoSidedUnboundedDependence places one target under the influence of both sides,
and RequiresBothSides demands both sides at once. flankWord is the witness family
instantiating the negative side: a target buried in a filler run between two
independently editable flanks. The non-interacting bimachines — the weak-determinism
class of [MMBMcC24], whose cell output is an order-independent
union of one-sided change-rules over the identity — live here with their exclusion and
separation theorems.
Main definitions #
LeftDetermined f i: output coordinateiis fixed by the prefixSet.Iic iBoundedDependence f s,UnboundedDependence f s: whether one margin caps the influence of sidesat every output coordinateTwoSidedUnboundedDependence f: for everyd, one base word carries a target flipped by far perturbations on either sideRequiresBothSides f: the target is changed, and either far perturbation alone reverts itOneSidedChanges f: every changed cell is determined by one side of its input aloneflankWord x fill y n: a target buried in a filler run with editable flanksBimachine.NonInteraction,Bimachine.IsNonInteracting: the cell output decomposed as an order-independent union of one-sided change-rules over the identityIsNonInteractingBimachineComputable f:fis computed by some non-interacting finite bimachine
Main theorems #
unboundedDependence_iff: every margin fails at some output coordinateRequiresBothSides.of_flanks: the three-map witness template — a map is excluded by three target-cell observationsIsNonInteractingBimachineComputable.oneSidedChanges: a non-interacting bimachine changes each cell from one sideIsLeftSubsequential.boundedDependence_right: a length-preserving left-subsequential function depends boundedly on the rightMealy.leftDetermined,Mealy.boundedDependence_right: a sequential machine is prefix-determined at every coordinateRequiresBothSides.not_isNonInteractingBimachineComputable: a map whose target needs both sides at once is computed by no non-interacting bimachinesetOf_isNonInteractingBimachineComputable_ssubset: the non-interacting class is proper inside the bimachine-computable functions
Implementation notes #
The coordinate predicates index the output coordinate and the input window
separately, which is informative for length-preserving functions; for block-emitting
transducers the two drift apart. BoundedDependence is the positive primitive; unboundedDependence_iff recovers
the margin-indexed witness form, and unpacking ¬ List.DependsOn yields word-pair
witnesses. The forms are margin-indexed rather than fixed-index because a fixed
target has only finitely many positions to its left.
The predicates place no in-range guard on target coordinates: for length-preserving
maps an out-of-range coordinate is none on both sides of any perturbation.
The dependence lattice #
Output coordinate i is fixed by the prefix Set.Iic i.
Equations
- LeftDetermined f i = List.DependsOn (fun (u : List α) => (f u)[i]?) (Set.Iic i)
Instances For
An equal-length variant of base differing only beyond the d-margin of target
i on side s.
Equations
- IsFarPerturbation base u i d s = (u.length = base.length ∧ Set.EqOn (fun (x : ℕ) => base[x]?) (fun (x : ℕ) => u[x]?) (s.window i d))
Instances For
f depends boundedly on side s: a single margin caps, at every output
coordinate, how far input on side s can matter.
Equations
- BoundedDependence f s = ∃ (N : ℕ), ∀ (i : ℕ), List.DependsOn (fun (u : List α) => (f u)[i]?) (s.window i N)
Instances For
f depends unboundedly on side s.
Equations
- UnboundedDependence f s = ¬BoundedDependence f s
Instances For
f fails unbounded dependence on side s exactly when its dependence there is
bounded.
Unbounded dependence coordinate-wise: every margin fails at some output coordinate.
A map whose every output coordinate is fixed by its prefix Set.Iic i depends
boundedly on the right.
A map whose every output coordinate is fixed by the input's strict prefix
Set.Iio i depends boundedly on the right.
For every d, one base word carries a target whose output flips under a far
perturbation on either side.
Equations
- TwoSidedUnboundedDependence f = ∀ (d : ℕ), ∃ (base : List α), ∃ i < base.length, ∀ (s : ScanDirection), ∃ (u : List α), IsFarPerturbation base u i d s ∧ (f base)[i]? ≠ (f u)[i]?
Instances For
Co-located two-sided dependence yields unbounded dependence on either side.
f requires both sides when some target changes under f yet perturbing either
far side reverts it to the identity.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Every changed cell is determined by the input on one side of it alone — which side may vary from cell to cell.
Equations
- OneSidedChanges f = ∀ (w : List α) (i : ℕ), (f w)[i]? ≠ w[i]? → ∃ (s : ScanDirection), List.DependsAt (fun (u : List α) => (f u)[i]?) (s.window i 0) w
Instances For
A map that requires both sides has a change no single side determines.
Requiring both sides strengthens two-sided unbounded dependence.
The flank-witness template #
The recurring witness family for two-sided unboundedness: a target buried in a filler
run, with independently editable flanks. RequiresBothSides.of_flanks packages the
whole assembly — a map is excluded by three target-cell observations: the base image
leaves the filler, and either single-flank perturbation restores it.
A non-filler value sits only on a flank.
The window up to the filler run is the left flank and part of the run.
The window past the left flank is the rest of the run and the right flank.
A window reaching at most the filler run contains a iff the left flank is a.
A window past the left flank contains a iff the right flank is a.
A flag over a window reaching at most the filler run reads the left flank.
A flag over a window past the left flank reads the right flank.
Changing only the left flank perturbs beyond the d-margin of a target past it.
Changing only the right flank perturbs beyond the d-margin of a target
d-clear of the last position.
A d-indexed family of flank words whose target's image flips under changing
either flank alone has two-sided unbounded dependence.
A d-indexed family of flank words whose target sits d-far from both flanks,
changed in the base and reverted by flipping either flank alone, requires both sides.
Non-interacting bimachines: the apparatus #
Non-interacting decompositions #
The output at a cell is determined by one side alone: fixing the input symbol and one context state already fixes it.
Equations
- B.OneSidedAt l a r = ((∀ (r' : R), B.output l a r' = B.output l a r) ∨ ∀ (l' : L), B.output l' a r = B.output l a r)
Instances For
unite cL cR a takes the left proposal if it fires (≠ a), else the right one —
the union of two change proposals over the identity default a. The tie-break is
asymmetric (when both fire the left wins) but inert under the order-independence
IsNonInteracting requires.
Equations
- Bimachine.unite cL cR a = if cL = a then cR else cL
Instances For
With the right proposal inert, the union is whatever the left one proposes.
With the left proposal inert, the union is whatever the right one proposes.
A firing left proposal wins.
The union is order-independent exactly when the proposals agree wherever both fire.
The combined value is the default exactly when both one-sided proposals are inert.
A non-interacting decomposition of a bimachine: a change-rule per side over the identity default, whose union is order-independent and produces the cell output.
- ruleL : L → α → α
The change the left context proposes for the current symbol.
- ruleR : R → α → α
The change the right context proposes for the current symbol.
- unite_comm (l : L) (a : α) (r : R) : unite (self.ruleL l a) (self.ruleR r a) a = unite (self.ruleR r a) (self.ruleL l a) a
The union of the two proposals is order-independent (
unite_comm_iff: they agree wherever both fire), so neither side can suppress the other's change. The cell output is the union of the two proposals.
Instances For
A bimachine over a single alphabet is non-interacting when it admits a
non-interacting decomposition (NonInteraction) of its cell output.
Equations
- B.IsNonInteracting = Nonempty B.NonInteraction
Instances For
A non-interacting decomposition exhibits the bimachine as letter-to-letter.
Equations
- w.letterToLetter = { cell := fun (l : L) (a : α) (r : R) => Bimachine.unite (w.ruleL l a) (w.ruleR r a) a, output_eq := ⋯ }
Instances For
A firing left rule alone determines the output.
A firing right rule alone determines the output — order-independence of the union is what silences the left state.
At every cell whose output differs from the input symbol, a decomposed bimachine is one-sided: the change is the left rule's alone or the right rule's alone.
At every cell whose output differs from the input symbol, a non-interacting bimachine is one-sided.
Transport a decomposition along state equivalences.
Equations
Instances For
Non-interaction transports along state reindexing.
A decomposed bimachine fixes cell i exactly when both change-proposals are inert
at its two context states.
The non-interacting class #
Computability by a non-interacting finite bimachine.
Equations
- IsNonInteractingBimachineComputable f = ∃ (L : Type) (x : Fintype L) (R : Type) (x : Fintype R) (B : Bimachine L R α α), B.run = f ∧ B.IsNonInteracting
Instances For
f is computed by a non-interacting finite bimachine if and only if it is computed
by one with state types in any universes.
A non-interacting finite-state bimachine witnesses
IsNonInteractingBimachineComputable for its run, whatever the universes of its
state types (IsNonInteracting.map).
A function computed by a non-interacting bimachine is in particular bimachine-computable.
Functions computed by non-interacting bimachines are length-preserving.
A Mealy-computable function is computed by a non-interacting bimachine: the
bimachine view (Mealy.toBimachine) has a trivial right automaton, so the cell output
is a one-sided rule with ωR the identity.
Machines bound dependence #
A length-preserving left-subsequential function depends boundedly on the right: the
delay bound of IsLeftSubsequential.exists_getElem?_append_eq is the dependence bound.
Sequential machines are the zero-delay case — prefix-determined at every coordinate
(Mealy.leftDetermined), which is strictly stronger than bounded right dependence.
A length-preserving left-subsequential function depends boundedly on the right.
A sequential machine is left-determined at every coordinate.
A sequential machine's output never depends on input to its right.
A Mealy-computable map is left-determined at every coordinate.
A Mealy-computable map's output never depends on input to its right.
Non-interacting bimachines #
A map that requires both sides escapes the non-interacting bimachines, and the conjunctive flag bimachine shows the non-interacting class is proper.
A map that requires both sides is computed by no non-interacting bimachine. At the
witness the base changes but each far perturbation reverts: the right perturbation
shares the left window, silencing ruleL at this cell; the left perturbation shares
the right window, silencing ruleR; yet the base needs one of them to fire.
Strictness: non-interacting ⊊ bimachine-computable #
A conjunctive change — a symbol raised iff a mark occurs on both sides — is bimachine-computable but requires both sides, so no non-interacting bimachine computes it.
The conjunctive flag bimachine: a false cell is raised exactly when a true
occurs on both sides.
Equations
- conjBM = Bimachine.ofFlags id id fun (l s r : Bool) => s || l && r
Instances For
The conjunctive change requires both sides: with a mark on each flank the medial cell is raised, and demoting either mark alone reverts it — the three-map template, one map per argument.
Changed cells of a non-interacting bimachine's run are each determined by a
single side, OneSidedAt transported to words.
The non-interacting class is proper inside the bimachine-computable functions —
conjBM is computed by a bimachine, but by no non-interacting one.