Erasing String Homomorphisms and Tier Projections #
A string homomorphism h : α* → β* is a monoid homomorphism on free
monoids: it satisfies h(uv) = h(u) ++ h(v) and h(ε) = ε. Such a map is
letterwise when it is determined by its action on single symbols, and
erasing when each symbol maps to at most one output symbol.
A tier projection in autosegmental phonology (@cite{goldsmith-1976}) and
in tier-based learning (@cite{belth-2026}) is exactly the letterwise erasing
case: a per-symbol partial map α → Option β, lifted to α* → β* via
List.filterMap. This is the morphism α → β in the Kleisli category of
Option over the free-monoid functor.
This module provides:
StringHom α β := α → List β— the general letterwise homomorphism.Tier α β := α → Option β— the erasing case.Tier.apply— lift toList α → List β(the projection itself).Tier.id,Tier.empty,Tier.byClass,Tier.total— constructors.
The monoid-homomorphism law (Tier.apply_append) holds definitionally
via List.filterMap_append; this is what licenses tier projections in OT
and HG constraint evaluation (mkOCP in Phonology/Constraints.lean
already takes a generic project : C → List α, so Tier.apply T plugs in
directly).
@cite{goldsmith-1976} @cite{belth-2026}
A letterwise string homomorphism α* → β*: a per-symbol map sending
each input symbol to a (possibly empty, possibly multi-symbol) output
string. Lifted to lists via List.flatMap.
Equations
- Core.StringHom α β = (α → List β)
Instances For
The letter-to-letter homomorphism induced by f : α → β: each input
symbol maps to a singleton output. The image of apply (letterMap f)
coincides with List.map f; see apply_letterMap.
Equations
- Core.StringHom.letterMap f a = [f a]
Instances For
A tier projection α* → β*: a per-symbol partial map.
Each input symbol either projects to one tier symbol or is erased.
This is the morphism α → β in the Kleisli category of Option, and
equivalently a letterwise erasing string homomorphism. The lift to
List α → List β is List.filterMap.
Equations
- Core.Tier α β = (α → Option β)
Instances For
Tier defined by a class predicate: keep symbols satisfying p, erase
the rest. The standard form for autosegmental tonal/featural tiers.
Following mathlib's Finset.filter / Multiset.filter convention,
p is Prop-valued with [DecidablePred], so call sites can pass
structural predicates (fun x => x = .l, fun x => IsCons x)
without inserting decide wrappers.
Equations
- Core.Tier.byClass p x = if p x then some x else none
Instances For
Tier defined by a total function: every symbol projects to its image.
Equations
- Core.Tier.total f = some ∘ f
Instances For
Tier projection distributes over concatenation. This is the monoid-homomorphism property — load-bearing for compositional tier-based constraint evaluation.
The identity tier is the identity on lists.
A class-predicate tier acts as List.filter. The right-hand side
inserts decide because List.filter is Bool-valued; consumers
that already work in Bool should use this lemma directly.
The last (rightmost) projected symbol of xs satisfying q. The
standard "preceding tier-adjacent context" lookup for rules like
@cite{belth-2026}'s Disagree(A, F) / C __ ∘ proj(·, T).
Instances For
The first (leftmost) projected symbol of xs satisfying q. The
symmetric right-context lookup for C / __ C ∘ proj(·, T) rules.