Classical.Structures.Magma¶
Magmas β the empty-theory base case¶
This is the Classical.Structures.Magma module of the Agda Universal Algebra Library.
A magma is a set equipped with a single binary operation, with no further axioms
imposed. Mathematically a magma is just an inhabitant of the type
Algebra Sig-Magma Ξ± Ο: an Sig-Magma-algebra in the sense of universal
algebra, with no theory to satisfy. This is the degenerate case of the general
classical-structure encoding X Ξ± Ο = Ξ£[ π¨ β Algebra πβ Ξ± Ο ] π¨ β¨ Th-X; the
Ξ£-wrapping vanishes when Th-X is empty (per
ADR-002 v2 Β§5) and the
representation collapses to a type alias.
This is also the first concrete classical structure to land in Milestone 3 (of the agda-algebras 3.0 upgrade) and, as such, this module's prose is normative for the signature-mechanics conventions every subsequent structure consumes.
Specifically: hyphen-separated <symbol>-Op
constructor naming (in the corresponding Signatures/X file), ar-<Structure>
arity-function naming, Sig-<Structure> signature-value naming, ASCII ^ for
operation-symbol interpretation, a named <Structure>-Op module housing the
curried user-facing accessors so that downstream code can open <Structure>-Op πΏ
once and use the binary operation in infix form a β b (mirroring the
open Magma M-and-then-a β b idiom of Algebra.Bundles), the curried-accessor
body _β_ = Curryβ (β-Op ^ _), and the opsTo<family> constructor pattern.
Semigroup, Monoid, Group, Lattice, and Ring all follow this template. (Deviations require an ADR.)
The type of magmas¶
Magma Ξ± Ο is the type of Sig-Magma-algebras whose carrier sits at level Ξ±
and whose underlying setoid equivalence sits at level Ο. Empty theory means
no Ξ£-wrapping; the alias makes use sites read Magma Ξ± Ο rather than
Algebra {π = Sig-Magma} Ξ± Ο.
Magma : (Ξ± Ο : Level) β Type (suc Ξ± β suc Ο) Magma Ξ± Ο = Algebra Ξ± Ο
(If it's not obvious why Algebra Ξ± Ο yields a magma here, note that the
Setoid.Algebras.Basic module is imported above with the signature parameter set to
π = Sig-Magma.)
The Magma-Op module: named accessors for a fixed magma¶
Domain, Carrier, and _β_ are exposed inside a named parametric module
Magma-Op. Users open Magma-Op π΄ at a use site to bring all three into
scope; the binary operation is then expressed using infix notation a β b, matching
the experience of using open Magma M with the standard library's
Algebra.Bundles.Magma module.
The name Magma-Op follows the hyphen-separated long-form convention established by
Sig-Magma, ar-Magma, and β-Op. It is normative: every subsequent classical
structure ships an analogously named module (Semigroup-Op, Monoid-Op, Group-Op,
Lattice-Op, Ring-Op). Each later module additively re-exports the underlying
weaker structure's operations through the forgetful projection; Group-Op exposes
_β_, Ξ΅, and _β»ΒΉ; Ring-Op exposes _+_, 0, -_, _Β·_, and 1. The
"open the operations module once, use infix thereafter" idiom is uniform across the
hierarchy.
The function _β_ interprets the syntactic operation symbol β-Op in the algebra
π΄ and then curries the resulting (Fin 2 β π[ π΄ ]) β π[ π΄ ] into the
user-facing π[ π΄ ] β π[ π΄ ] β π[ π΄ ]. The arity-tuple-vs-curried bridging is
delegated to Curryβ from Classical.Operations; the per-structure file never
constructs pair-style argument tuples inline. This is what
ADR-002 Β§1 requires: the Fin n
Ξ·-bridge is contained inside one module library-wide.
When two magmas appear in the same expression β for example, both sides of a
round-trip lemma in Classical.Bundles.Magma β the standard Agda idiom is
open Magma-Op π΄
open Magma-Op π΅ renaming (_β_ to _β'_)
module Magma-Op {Ξ± Ο : Level} (π΄ : Magma Ξ± Ο) where infixl 7 _β_ _β_ : π[ π΄ ] β π[ π΄ ] β π[ π΄ ] _β_ = Curryβ (β-Op ^ π΄)
From a bare type and a binary operation¶
The single most common use case for downstream consumers is constructing a magma
from a bare type A : Type Ξ± and a binary operation _Β·_ : A β A β A.
The opsToMagma function performs the construction. The underlying setoid is
the propositional-equality setoid β‘.setoid A, and the interpretation of β-Op
uncurries _Β·_ back into the tuple-indexed form the algebra demands.
For structures with non-empty theory, the analogous constructor takes one additional
argument per equation in the theory β eqsToSemigroup takes an associativity
proof, eqsToMonoid takes associativity plus the two identity laws, and so on.
Magma's empty theory means opsToMagma takes no equation arguments. This is the
empty-theory edge case of the opsTo<family> constructor pattern.
opsToMagma : {A : Type Ξ±} (_Β·_ : A β A β A) β Magma Ξ± Ξ± opsToMagma {A = A} _Β·_ = record { Domain = β‘.setoid A ; Interp = interp } where interp : Func (β¨ Sig-Magma β© _) _ interp β¨$β© (β-Op , args) = args 0F Β· args 1F cong interp {β-Op , _} {.β-Op , _} (β‘.refl , argsβ‘) = β‘.congβ _Β·_ (argsβ‘ 0F) (argsβ‘ 1F)
A note on morphisms¶
A magma morphism is, by ADR-002 Β§5, definitionally a homomorphism of the
underlying Sig-Magma-algebras. No per-structure morphism record is introduced; we
inherit Setoid.Homomorphisms wholesale, instantiated at π = Sig-Magma. This
is uniformly the policy across the classical hierarchy: each structure inherits
homomorphisms, isomorphisms, and substructure machinery from Setoid/
instantiated at its own signature. Per-structure morphism invariants β for
example, "monoid homomorphisms preserve the identity element" β are theorems
about the inherited homomorphism, not new record fields.
The first such invariant is the inherited homomorphism's compatibility with β-Op
restated in curried form: h (x β y) β h x β h y. The compatible field of
IsHom states this against argument tuples (h ((β-Op ^ π¨) a) β (β-Op ^ π©) (h β a));
hom-preserves-β instantiates the tuple at pair x y and pays the Fin 2 Ξ·-bridge
once, via interp-cong, so downstream consumers
(e.g. the free-expansion functor) get the curried law as a one-liner.
module _ {Ξ± Ξ² Οα΅ Οα΅ : Level} {π¨ : Magma Ξ± Οα΅} {π© : Magma Ξ² Οα΅} where open Magma-Op π¨ using ( _β_ ) open Magma-Op π© using () renaming ( _β_ to _βα΅_ ) open Setoid π»[ π© ] using () renaming ( _β_ to _βα΅_ ; refl to βα΅-refl ; trans to βα΅-trans ) -- Magma homomorphisms preserve the binary operation, in curried form. hom-preserves-β : (h : hom π¨ π©) (x y : π[ π¨ ]) β projβ h β¨$β© (x β y) βα΅ (projβ h β¨$β© x) βα΅ (projβ h β¨$β© y) hom-preserves-β h x y = βα΅-trans (IsHom.compatible (projβ h) {β-Op} {pair x y}) (interp-cong π© β-Op (Ξ» { 0F β βα΅-refl ; 1F β βα΅-refl }))