Many-sorted algebra: core layer
DefinitionMSKleene_Core(updated) Many-sorted algebra: core layer. See the mission's other definition items for the surrounding development.
/-
Many-sorted universal algebra: the core layer for the mission
"A Kleene Theorem for Free Many-Sorted Algebras"
(Gong, Ruiz Mora, Sanmartín Vich, Cosme Llópez, 2026).
This file fixes the representation of:
* S-sorted sets and S-sorted subsets (paper, Section 2.1)
* S-sorted signatures (Definition 2.25)
* many-sorted Σ-algebras and Σ-homomorphisms (Definition 2.26)
* the free Σ-algebra T_Σ(X) as an inductive term type (Definitions 3.1, 3.2)
* evaluation of terms into an algebra (universal property, Prop. 3.5)
* the power Σ-algebra A^℘ (Proposition 2.32)
Conventions: the set of sorts `S` is a type; finiteness is required by later
results and is carried as an explicit `[Fintype S]` where needed.
-/
import Mathlib.Data.Fintype.Basic
import Mathlib.Data.Fintype.Sigma
import Mathlib.Data.Set.Basic
import Mathlib.Data.List.Basic
namespace MSKleene
universe u
/-- An `S`-sorted set is a family of types indexed by the sorts. -/
abbrev SSet (S : Type u) : Type (u + 1) := S → Type u
/-- An `S`-sorted map between `S`-sorted sets is a sortwise family of maps. -/
def SMap {S : Type u} (A B : SSet S) : Type u := (s : S) → A s → B s
/-- An `S`-sorted subset of `A`: a sortwise family of subsets. This is the
underlying `S`-sorted set of the power object `A^℘`. -/
def SSub {S : Type u} (A : SSet S) : Type u := (s : S) → Set (A s)
instance {S : Type u} (A : SSet S) : PartialOrder (SSub A) where
le X Y := ∀ s, X s ⊆ Y s
le_refl X s := le_refl _
le_trans X Y Z hXY hYZ s := le_trans (hXY s) (hYZ s)
le_antisymm X Y hXY hYX := funext fun s => le_antisymm (hXY s) (hYX s)
/-- Kronecker delta `δ^{t,U}`: the `S`-sorted subset that is `U` at sort `t`
and empty elsewhere (Definition 2.5). -/
def delta {S : Type u} [DecidableEq S] {A : SSet S} (t : S) (U : Set (A t)) : SSub A :=
fun s => if h : s = t then h ▸ U else (∅ : Set (A s))
/-- An `S`-sorted set is finite when the disjoint union of its components is. -/
def SFinite {S : Type u} (A : SSet S) : Prop := Finite (Σ s, A s)
/-! ### Signatures -/
/-- An `S`-sorted signature assigns to an arity `w : List S` and a coarity
`s : S` the set of operation symbols of that rank (Definition 2.25). -/
def Signature (S : Type u) : Type (u + 1) := List S → S → Type u
/-- A signature is **finite** when it has only finitely many operation symbols
in total, across all ranks. -/
def SigFinite {S : Type u} (sig : Signature S) : Prop :=
Finite ((w : List S) × (s : S) × sig w s)
/-- The argument tuple of arity `w` over an `S`-sorted set `A`: one element of
`A (w[i])` for each position `i`. -/
def Args {S : Type u} (A : SSet S) : List S → Type u
| [] => PUnit
| s :: w => A s × Args A w
/-- Map an `S`-sorted map over an argument tuple. -/
def Args.map {S : Type u} {A B : SSet S} (f : SMap A B) :
{w : List S} → Args A w → Args B w
| [], _ => PUnit.unit
| _ :: _, (a, rest) => (f _ a, Args.map f rest)
/-- `Args.All P as` — every component of the argument tuple `as` satisfies `P`. -/
def Args.All {S : Type u} {A : SSet S} (P : (s : S) → A s → Prop) :
{w : List S} → Args A w → Prop
| [], _ => True
| _ :: _, (a, rest) => P _ a ∧ Args.All P rest
@[simp] theorem Args.map_id {S : Type u} {A : SSet S} :
∀ {w : List S} (args : Args A w), Args.map (fun _ a => a) args = args
| [], _ => rfl
| _ :: _, (a, rest) => congrArg (Prod.mk a) (Args.map_id rest)
theorem Args.map_comp {S : Type u} {A B C : SSet S} (g : SMap B C) (f : SMap A B) :
∀ {w : List S} (args : Args A w),
Args.map (fun s a => g s (f s a)) args = Args.map g (Args.map f args)
| [], _ => rfl
| _ :: _, (a, rest) => congrArg (Prod.mk (g _ (f _ a))) (Args.map_comp g f rest)
/-! ### Algebras and homomorphisms -/
/-- A many-sorted `Σ`-algebra: an `S`-sorted carrier together with an
interpretation of every operation symbol (Definition 2.26). -/
structure Algebra {S : Type u} (sig : Signature S) where
carrier : SSet S
op : {w : List S} → {s : S} → sig w s → Args carrier w → carrier s
/-- A `Σ`-homomorphism: a sortwise family of maps commuting with every
operation (Definition 2.26). -/
structure Hom {S : Type u} {sig : Signature S} (A B : Algebra sig) where
toFun : SMap A.carrier B.carrier
map_op : ∀ {w : List S} {s : S} (σ : sig w s) (args : Args A.carrier w),
toFun s (A.op σ args) = B.op σ (Args.map toFun args)
/-- The identity homomorphism. -/
def Hom.id {S : Type u} {sig : Signature S} (A : Algebra sig) : Hom A A where
toFun := fun _ a => a
map_op := by intro w s σ args; simp
/-- Composition of homomorphisms. -/
def Hom.comp {S : Type u} {sig : Signature S} {A B C : Algebra sig}
(g : Hom B C) (f : Hom A B) : Hom A C where
toFun := fun s a => g.toFun s (f.toFun s a)
map_op := by
intro w s σ args
rw [f.map_op, g.map_op, Args.map_comp]
end MSKleene
Read-back
What the Lean code literally says, in plain math · claude-sonnet-5
SSet
For a type (in universe ), is defined to be the type of functions . An element is therefore an -indexed family of types; the value of at an index is written below. This type itself lives one universe level up (). It is introduced as an abbreviation, so it is definitionally equal to and unfolds freely.
SMap
Given an implicit type and two explicit families , the type is defined to be the dependent function type
That is, an element of assigns to every index a function from to . No compatibility or naturality condition is imposed; it is just an index-wise family of ordinary functions.
SSub
Given an implicit type and an explicit family , the type is defined to be
where is the type of subsets of (predicates on ). So an element picks out, for each index , a subset .
PartialOrder (SSub A) instance
For every implicit type and every , this registers a partial-order structure on . The order is defined by
i.e. index-wise inclusion of subsets. The instance also supplies the three proofs making this a partial order: reflexivity ( always holds, since for each ); transitivity (if and then , by chaining at each ); and antisymmetry (if and then , obtained by function extensionality over together with antisymmetry of set inclusion at each index). In particular equality of elements of is index-wise equality of subsets.
delta
Given an implicit type equipped with decidable equality, an implicit family , an explicit index , and an explicit subset , the term is the element of whose value at an index is:
In the first branch, where a proof is available, (a subset of ) is reinterpreted as a subset of by transporting along the equality . In every branch with the value is the empty subset of . So is the family that is concentrated at the single index , carrying there and nothing anywhere else.
SFinite
Given an implicit type and an explicit family , is defined to be the proposition that the dependent-sum type
(the total space of the family, whose elements are pairs with ) is a finite type, in the sense of Mathlib's Finite typeclass-style predicate. This simultaneously constrains and every fiber : the disjoint union of all fibers must have finitely many elements. It says nothing directly beyond finiteness of that sigma type (e.g. it is satisfied when is empty).
Signature
For a type (in universe ), is defined to be the type of functions
An element therefore assigns, to each finite word of input sorts and each output sort , a type ; this type is to be thought of as the collection of operation symbols with input arity and result sort . The type lives in .
SigFinite
Given an implicit type and an explicit , is defined to be the proposition that the iterated dependent-sum type
is finite (Finite). Elements of that type are triples consisting of an input word , an output sort , and an operation symbol in . So asserts that, across all input words and all output sorts together, there are only finitely many operation symbols in total.
Args
Given an implicit type and an explicit family , is a function defined by recursion on the list:
Here is a one-element type. Consequently, for a word , the type is the nested product : a tuple with exactly one entry drawn from for each position of the word, and for the empty word it is the singleton type.
Args.map
Given an implicit type , implicit families , an explicit (an index-wise family of functions ), and an implicit word , the function maps by recursion on :
- on the empty word it returns the unique element ;
- on a cons word, given a pair with for the head sort , it returns .
In effect it applies at the appropriate sort to each component of the tuple, leaving the shape (the word ) unchanged.
Args.All
Given an implicit type , an implicit family , an explicit predicate , and an implicit word , is a predicate on defined by recursion on :
where is the head sort. Thus holds exactly when holds of every component of the tuple ; for the empty word it is vacuously true.
Args.map_id
This theorem (tagged as a simp lemma) states: for every implicit type and every family , for every implicit word and every tuple ,
That is, mapping the tuple with the family of identity functions (the function that at every sort sends to ) yields the original tuple unchanged.
Args.map_comp
This theorem states: for every implicit type , implicit families , explicit and explicit , for every implicit word and every tuple ,
That is, mapping with the index-wise composite of after equals first mapping with and then mapping the result with .
Algebra
Given an implicit type and an explicit signature , the structure bundles two data:
- a field , an -indexed family of types (the underlying carriers, one per sort);
- a field : for every implicit word and every implicit sort , a function taking an operation symbol and an argument tuple in and producing an element of .
So an algebra interprets each operation symbol of profile as an actual operation from tuples of carrier elements matching to a carrier element of sort . No equational axioms are imposed.
Hom
Given an implicit type , an implicit signature , and two explicit algebras , the structure bundles:
- a field , i.e. for each sort a function ;
- a field : for all implicit and implicit , for every operation symbol and every argument tuple ,
That is, applying the map after an -operation equals applying the corresponding -operation to the componentwise-mapped arguments, for every operation symbol.
Hom.id
Given an implicit type , an implicit signature , and an explicit algebra , is the element of whose is the index-wise identity (at every sort, ), together with the required proof of the condition for this choice (discharged by simplification).
Hom.comp
Given an implicit type , an implicit signature , implicit algebras , an explicit and an explicit , the term is the element of whose at each sort is , together with a proof of its condition (established using the fields of and and the lemma ). Note the argument order: is "first , then ".
Confirmed by the mission captain (proposal self-audit).