The free many-sorted algebra
DefinitionMSKleene_TermThe free -algebra on an -sorted set of variables (Definitions 3.1, 3.2), represented by the mutual inductive Term / TermVec: a term is a variable var x or an operation symbol applied to a vector of subterms of the matching arity, app σ ts (a constant is app σ .nil).
The file provides the algebra structure freeAlgebra (carrier Term sig X, operations app), the insertion of generators eta (), the evaluation Term.eval of a term in an arbitrary -algebra A under an assignment ρ : X → A, and the induced homomorphism evalHom with evalHom_eta : evalHom A ρ ∘ η^X = ρ. This is the existence half of the universal property of (Proposition 3.5).
Formalization Note TermVec sig X w is a heterogeneous list holding one subterm of sort w[i] per argument position; ofArgs / toArgs convert between it and the nested-product Args.
/-
The free many-sorted `Σ`-algebra `T_Σ(X)` (Definitions 3.1, 3.2) as an
inductive family of terms, together with:
* its `Algebra` structure (`freeAlgebra`);
* the insertion of generators `η^X`;
* evaluation of a term into any `Σ`-algebra under an assignment, and the
induced homomorphism (the existence half of the universal property, Prop. 3.5).
Terms are represented by the mutual inductive `Term` / `TermVec`, the standard
encoding of many-sorted terms: `TermVec sig X w` is a heterogeneous list holding
one subterm of sort `w[i]` per argument position.
-/
import Definitions.Def_MSKleene_Core
namespace MSKleene
universe u
variable {S : Type u}
-- Many-sorted terms over signature `sig` with variables in `X`:
-- `var` injects a variable; `app` applies an operation symbol to a vector of
-- subterms of the matching arity (a constant is `app σ .nil`).
-- `TermVec sig X w` is a heterogeneous list holding one subterm of sort `w[i]`
-- per argument position.
mutual
inductive Term (sig : Signature S) (X : SSet S) : S → Type u where
| var {s : S} : X s → Term sig X s
| app {w : List S} {s : S} : sig w s → TermVec sig X w → Term sig X s
inductive TermVec (sig : Signature S) (X : SSet S) : List S → Type u where
| nil : TermVec sig X []
| cons {s : S} {w : List S} : Term sig X s → TermVec sig X w → TermVec sig X (s :: w)
end
/-- Convert an `Args` tuple of terms into a `TermVec`. -/
def TermVec.ofArgs {sig : Signature S} {X : SSet S} :
{w : List S} → Args (Term sig X) w → TermVec sig X w
| [], _ => .nil
| _ :: _, (t, rest) => .cons t (TermVec.ofArgs rest)
/-- Convert a `TermVec` back into an `Args` tuple of terms. -/
def TermVec.toArgs {sig : Signature S} {X : SSet S} :
{w : List S} → TermVec sig X w → Args (Term sig X) w
| [], _ => PUnit.unit
| _ :: _, .cons t rest => (t, TermVec.toArgs rest)
/-- The free `Σ`-algebra `T_Σ(X)`: carrier `Term sig X`, operations `app`
(Definition 3.2). -/
def freeAlgebra (sig : Signature S) (X : SSet S) : Algebra sig where
carrier := Term sig X
op := fun σ args => Term.app σ (TermVec.ofArgs args)
/-- Insertion of the generators, `η^X : X → T_Σ(X)` (Proposition 3.5). -/
def eta (sig : Signature S) (X : SSet S) : SMap X (freeAlgebra sig X).carrier :=
fun _ x => Term.var x
-- Evaluate a term in the algebra `A` under the assignment `ρ : X → A`.
-- Together with `evalArgs` this is the unique-extension map of Proposition 3.5.
mutual
def Term.eval {sig : Signature S} {X : SSet S} (A : Algebra sig)
(ρ : SMap X A.carrier) : {s : S} → Term sig X s → A.carrier s
| _, .var x => ρ _ x
| _, .app σ ts => A.op σ (TermVec.evalArgs A ρ ts)
def TermVec.evalArgs {sig : Signature S} {X : SSet S} (A : Algebra sig)
(ρ : SMap X A.carrier) : {w : List S} → TermVec sig X w → Args A.carrier w
| [], _ => PUnit.unit
| _ :: _, .cons t ts => (Term.eval A ρ t, TermVec.evalArgs A ρ ts)
end
theorem TermVec.evalArgs_ofArgs {sig : Signature S} {X : SSet S} (A : Algebra sig)
(ρ : SMap X A.carrier) :
∀ {w : List S} (args : Args (Term sig X) w),
TermVec.evalArgs A ρ (TermVec.ofArgs args)
= Args.map (fun s (t : Term sig X s) => Term.eval A ρ t) args
| [], _ => rfl
| _ :: _, (t, rest) => congrArg (Prod.mk (Term.eval A ρ t))
(TermVec.evalArgs_ofArgs A ρ rest)
/-- The homomorphism `ρ^♯ : T_Σ(X) → A` induced by an assignment `ρ`
(the existence half of Proposition 3.5). -/
def evalHom {sig : Signature S} {X : SSet S} (A : Algebra sig)
(ρ : SMap X A.carrier) : Hom (freeAlgebra sig X) A where
toFun := fun _ t => Term.eval A ρ t
map_op := by
intro w s σ args
show Term.eval A ρ (Term.app σ (TermVec.ofArgs args)) = _
show A.op σ (TermVec.evalArgs A ρ (TermVec.ofArgs args)) = _
exact congrArg (A.op σ) (TermVec.evalArgs_ofArgs A ρ args)
/-- `ρ^♯ ∘ η^X = ρ`: the induced homomorphism restricts to `ρ` on generators. -/
theorem evalHom_eta {sig : Signature S} {X : SSet S} (A : Algebra sig)
(ρ : SMap X A.carrier) (s : S) (x : X s) :
(evalHom A ρ).toFun s (eta sig X s x) = ρ s x := rfl
end MSKleene
Read-back
What the Lean code literally says, in plain math · claude-sonnet-5
Term and TermVec (mutually inductive families)
Throughout, is an implicit type of sorts. Fixed as explicit parameters are a signature over — a rule assigning to each pair consisting of a word and a sort a type , thought of as the operation symbols of argument profile and result sort — and a sort-indexed family of variable types , assigning to each sort a type . The declaration introduces, simultaneously, two inductive families valued in :
- , where is meant to be the terms of sort ;
- , where is meant to be the finite sequences of terms whose sorts are exactly the entries of , in order.
has two constructors. The constructor takes an implicit sort and an element and returns . The constructor takes an implicit word , an implicit sort , an operation symbol , and a term-vector , and returns . has two constructors: , and , which takes an implicit sort , an implicit word , a term and a vector , and returns , where is the list with head and tail . Being inductive, and are the least families closed under these constructors: every element is built from finitely many applications of , , , . Nullary operation symbols give constant terms . No finiteness or decidability hypothesis is imposed on , , or ; if some is empty there are simply no -terms of that sort.
TermVec.ofArgs
For implicit , implicit , and implicit word , this defines a function
Here is the iterated product type defined by recursion on : is the one-element type , and ; so is a tuple holding one term for each sort listed in (plus a trailing unit). The function is defined by recursion on : on the empty word, the unique input is sent to ; on , an input which is a pair with and is sent to .
TermVec.toArgs
For implicit , , and , this defines the reverse conversion
by recursion on : on the empty word it returns the unique element of ; on it matches an input of the form and returns the pair .
freeAlgebra
Given explicit parameters and , this produces an element of . An is a structure consisting of a carrier family together with an operation map that, for implicit and , takes an operation symbol and a tuple and returns an element of . For the carrier family is itself, and the operation map sends and to the term .
eta
Given explicit parameters and , this produces an element of , that is, a family of functions (one for each sort ). The function ignores its sort argument in the sense that at every sort it is given by .
Term.eval and TermVec.evalArgs (mutually recursive)
Fix implicit and , an explicit algebra , and an explicit assignment , i.e. a family of functions . This mutually defines two total functions.
takes an implicit sort and a term of and returns an element of , by structural recursion:
takes an implicit word and a vector of and returns an element of , by recursion on : the empty vector is sent to the unique element of ; a vector is sent to the pair .
TermVec.evalArgs_ofArgs
For all implicit and , every algebra , every assignment , every implicit word , and every tuple , the following equality of elements of holds:
where applies the sort-indexed function componentwise to every entry of a tuple. In words: converting into a term-vector and then evaluating that vector yields the same tuple as evaluating each component term of individually.
evalHom
For implicit and , an explicit algebra and an explicit assignment , this produces an element of . A is a structure bundling a sorted map together with a proof that it commutes with every operation. For , the map is, at every sort, , and the bundled proof asserts that for all implicit , , every operation symbol and every ,
i.e. that applying the evaluation map to the free algebra's interpretation of agrees with 's interpretation of applied to the pointwise-evaluated arguments.
evalHom_eta
For all implicit and , every algebra , every assignment , every sort , and every variable , the following holds:
Unfolding the definitions, is and the underlying map of is , so this states . It is asserted to hold by reflexivity, i.e. definitionally.
Confirmed by the mission captain (proposal self-audit).