definition example theorem proof program

A (deterministic) finite state machine is a quintuple : a finite nonempty input alphabet , a finite nonempty state set , a state-transition function , an initial state and a set of final states. Category Theory for Scientists ignores and and focuses on how the alphabet acts on the states:

Slogan (CTfS 3.1.2.12). A finite state machine is an action of a free monoid on a finite set.

Proposition (CTfS 3.1.2.11). For finite nonempty , giving a function is equivalent to giving an action of the Free Monoid on (Monoid Action).

Proof. An action of restricts to on one-letter words. Conversely, given , define the action of a word by recursion: and . This satisfies the two action laws, and the two constructions are mutually inverse (CTfS Exercise 3.1.2.13). Conceptually this is the universal property of the free monoid, , combined with Currying.

(With this recursion the last letter acts first, so strictly speaking one gets a right action — CTfS’s footnote 5; reading words left to right gives the left action of the opposite monoid.)

Sources: CTfS §3.1.2.10 (Figure 3.1, Proposition 3.1.2.11, Slogan 3.1.2.12, Exercise 3.1.2.13), Example 3.1.3.1, Exercise 3.1.4.15, Application 4.3.1.2, Example 4.3.2.15, Exercises 4.3.2.13, 4.6.2.5; DaoFP Chapter 13 (state machines as coalgebras ).

The example of CTfS Figure 3.1

Alphabet , states (initial state , final states ), with action table (CTfS Example 3.1.3.1):

state
012
121
200
012ababa;b012ababa;b

The drawn state diagram is the generating graph of the Category of Elements of the action (CTfS Exercise 4.6.2.5). Restricting scalars along , , gives a one-button machine: , , (the same in either reading order of the word) (CTfS Exercise 3.1.4.15).

Morphisms: refining a model

A morphism of state machines on the same alphabet is an equivariant map, i.e. a Natural Transformation between the functors . CTfS Application 4.3.1.2: a collaborator proposes a 6-state machine (states ) that is “compatible” with the 3-state above; the compatibility is exactly a natural transformation collapsing the letters. Only the squares for the generators need checking, since longer words follow by pasting squares. Natural isomorphisms are relabelings of states (CTfS Exercise 4.3.2.13). Adding a button for a frequently used sequence is precomposition with a monoid homomorphism , and the refinement survives by whiskering (CTfS Example 4.3.2.15).

Variations

Docs: Categories & functors · C-set morphisms · ACSets API · Theories & presentations

using Catlab
# CTfS Figure 3.1 / Example 3.1.3.1 as an instance on the schema with one object and two loops
@present SchFSM(FreeSchema) begin
  State::Ob
  (a, b)::Hom(State, State)
end
@acset_type FSM(SchFSM)
X = @acset FSM begin State = 3; a = [2, 3, 1]; b = [3, 2, 1] end   # states 0,1,2 ↦ rows 1,2,3
run(M, word, s) = foldl((s, σ) -> M[s, σ], word; init = s)          # the action of List(Σ)
run(X, [:a, :b, :b], 1)                                             # 2, i.e. State 1
# the refined 6-state model Y of Application 4.3.1.2 and the natural transformation Y ⇒ X
Y = @acset FSM begin
  State = 6                     # 0, 1A, 1B, 1C, 2A, 2B
  a = [2, 5, 6, 6, 1, 1]
  b = [5, 3, 4, 3, 1, 1]
end
α = homomorphism(Y, X; initial = (State = [1, 2, 2, 2, 3, 3],))
is_natural(α)                                                       # true: Y refines X
import Mathlib
#check @DFA                    -- structure: step : σ → α → σ, start, accept
#check @DFA.evalFrom           -- the action of a word (a `List α`) on a state
#check @DFA.evalFrom_append    -- evalFrom s (x ++ y) = evalFrom (evalFrom s x) y : the action law
#check @FreeMonoid.lift        -- Hom(FreeMonoid α, M) ≃ (α → M): the proof of Proposition 3.1.2.11
data Sym = A | B deriving (Eq, Show)
data St  = S0 | S1 | S2 deriving (Eq, Show)
 
delta :: Sym -> St -> St          -- the action table of CTfS Example 3.1.3.1
delta A S0 = S1; delta B S0 = S2
delta A S1 = S2; delta B S1 = S1
delta A S2 = S0; delta B S2 = S0
 
run :: [Sym] -> St -> St          -- the induced action of the free monoid [Sym]
run w s = foldl (flip delta) s w  -- run [] = id,  run (u ++ v) = run v . run u