Bimachines #
A Bimachine, in the sense of Schützenberger and Eilenberg, reads its input in both
directions: a left automaton scans →, a right automaton scans ←, and output i is
output (lState (x.take i)) (x i) (rState (x.drop (i+1))). By the theorem of Elgot and Mezei,
word-output bimachines compute exactly the rational functions; they are the transducers of
Schützenberger's semi-monomial representations, as Sakarovitch presents them. The
letter-to-letter machines here compute the total length-preserving ones.
Main definitions #
Bimachine L R α β: machine with left statesL, right statesR, alphabetsα,βBimachine.run: the computed functionBimachine.reverse: the mirror machine, the two automata trading sidesIsBimachineComputable f:fis computed by some finite bimachine
Main theorems #
Bimachine.LetterToLetter.getElem?_run: outputiisoutput (lState (x.take i)) (x i) (rState (x.drop (i+1)))Bimachine.run_reverse: the mirror machine computes the reverse conjugateIsBimachineComputable.revConj: the class is closed under reverse conjugation
Implementation notes #
Only the left state is threaded through the run (Bimachine.runFrom); the recursion
reads each tail's right state on the spot. The class existentials pin state types at
Type 0; the universe-polymorphic isBimachineComputable_iff recovers generality.
The identification of
IsBimachineComputable with the total rational functions preserving the empty word is
classical and not formalized here; ElgotMezei.lean proves the composition half.
References #
A bimachine is a left automaton scanning left to right, a right automaton scanning right to left, and a cell output reading both context states and the current symbol.
- lInit : L
The left automaton starts in this state.
- lStep : L → α → L
The left automaton steps on each symbol, scanning left to right.
- rInit : R
The right automaton starts in this state.
- rStep : R → α → R
The right automaton steps on each symbol, scanning right to left.
- output : L → α → R → List β
A cell emits a word from the two context states and the current input symbol.
Instances For
B.lStateAfter l pre is the left state reached from l after scanning pre.
Equations
- B.lStateAfter l = List.foldl B.lStep l
Instances For
Letter-to-letter bimachines #
A cell of a general bimachine emits a word, so the run is a concatenation and output positions need not track input positions. A letter-to-letter bimachine emits exactly one symbol per cell ([Sak09] §IV.6); the function it computes is then length-preserving, and the positional description below holds.
A witness that B is letter-to-letter names, by cell, the one symbol every cell
emits.
- cell : L → α → R → β
cell l a ris the symbol the cell emits. Every cell emits exactly that one symbol.
Instances For
B is letter-to-letter when it admits a LetterToLetter witness.
Equations
- B.IsLetterToLetter = Nonempty B.LetterToLetter
Instances For
The run of a letter-to-letter bimachine has the length of its input.
Output coordinate i reads the left state after the length-i prefix and the
right state of the strict suffix.
Output i is cell (lState (x.take i)) (x i) (rState (x.drop (i+1))).
Transport along state equivalences #
Transport a bimachine along equivalences on the two state spaces.
Equations
- One or more equations did not get rendered due to their size.
Instances For
reindex eL eR is map eL eR as an equivalence of bimachines.
Equations
- Bimachine.reindex eL eR = { toFun := Bimachine.map eL eR, invFun := Bimachine.map eL.symm eR.symm, left_inv := ⋯, right_inv := ⋯ }
Instances For
Cells agree exactly when the underlying word-valued outputs do.
Letter-to-letter-ness transports along state reindexing.
Equations
Instances For
Reversal #
Read backwards, a bimachine is again a bimachine: the two automata trade sides and every
cell emits its word reversed. The mirror computes the reverse conjugate, so the
bimachine-computable functions are closed under List.revConj.
Flag bimachines #
The recurring two-sided-trigger shape: each side's automaton is the one-bit "some symbol
on my side satisfies p" flag, so lState/rState compute List.any and the cell sees
exactly the two flags. The conjunctive witness conjBM below is an instance.
The bimachine whose side states are "a symbol satisfying pL/pR occurred on my
side" flags.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A flag bimachine is letter-to-letter, with out as its cell.
Equations
- Bimachine.ofFlags_letterToLetter pL pR out = { cell := out, output_eq := ⋯ }
Instances For
Output i of a flag bimachine sees the input symbol and the two window-any
flags.
Sequential machines as bimachines #
The bimachine view computes the same string function.
The bimachine-computable class #
Computability by a finite bimachine — classically, the total rational functions preserving the empty word.
Equations
- IsBimachineComputable f = ∃ (L : Type) (x : Fintype L) (R : Type) (x : Fintype R) (B : Bimachine L R α β), B.run = f
Instances For
f is bimachine-computable if and only if it is computed by a finite bimachine
with state types in any universes.
The reverse conjugate of a bimachine-computable function is bimachine-computable.
f is computed by a finite letter-to-letter bimachine. These are the total
length-preserving rational functions.
Equations
- IsLengthPreservingBimachineComputable f = ∃ (L : Type) (x : Fintype L) (R : Type) (x : Fintype R) (B : Bimachine L R α β), B.IsLetterToLetter ∧ B.run = f
Instances For
f is computed by a finite letter-to-letter bimachine iff it is computed by one with
state types in any universes.
A length-preserving bimachine-computable function is bimachine-computable.
Functions computed by letter-to-letter bimachines are length-preserving.
A Mealy-computable function is bimachine-computable (Mealy.toBimachine).