Setoid.Algebras.Basic¶
Basic definitions¶
This is the Setoid.Algebras.Basic module of the Agda Universal Algebra Library.
ov : Level β Level ov Ξ± = π β π₯ β lsuc Ξ±
Setoid Algebras¶
Here we define algebras over a setoid, instead of a mere type with no equivalence on it.
The operator β¨_β© that translates an ordinary signature into a
signature over a setoid domain β together with its companion EqArgs
β is defined in the signature-generic module Setoid.Signatures and imported
here (see the import above). Each takes its own signature argument rather than
reading this module's {π}, so housing them in a non-parameterized module means
the unused {π : Signature π π₯} parameter of this module does not ride along as
an unsolvable metavariable at use sites. The Interp field of
Algebra applies the imported β¨ π β© to this module's signature π.
Because the carrier of β¨ π β© Domain is a Ξ£-type β an operation symbol paired with
its argument tuple β an Interp clause matches it as (o , args), which
needs the pair constructor _,_ in scope. We therefore re-export _,_ and
Ξ£-syntax from this module (and hence from the Setoid.Algebras barrel),
so that pattern-matching such a carrier needs no separate Data.Product import β and no
longer trips the misleading "β-Op is not a constructor of the datatype β¦ Ξ£" error,
which points at the operation symbol rather than at the missing _,_.
open Func renaming ( to to _β¨$β©_ ; cong to βcong )
A setoid algebra is just like an algebra but we require that all basic operations
of the algebra respect the underlying setoid equality. The Func record packs a
function (f, aka apply, aka _β¨$β©_) with a proof (cong) that the function respects
equality.
record Algebra Ξ± Ο : Type (π β π₯ β lsuc (Ξ± β Ο)) where field Domain : Setoid Ξ± Ο Interp : Func (β¨ π β© Domain) Domain -- ^^^^^^^^^^^^^^^^^^^^^^^ is a record type with two fields: -- 1. a function f : Carrier (β¨ π β© Domain) β Carrier Domain -- 2. a proof cong : f Preserves _ββ_ βΆ _ββ_ (that f preserves the setoid equalities) open Setoid Domain using ( _β_ ) -- Actually, we already have the following: (it's called "reflexive"; see Structures.IsEquivalence) β‘ββ : β{x}{y} β x β‘ y β x β y β‘ββ refl = Setoid.refl Domain open Algebra
The next three definitions are merely syntactic sugar that we sometimes use to make the code more readable.
π»[_] : Algebra Ξ± Ο β Setoid Ξ± Ο π»[ π¨ ] = Domain π¨ -- Forgetful functor: returns the carrier of (the domain of) π¨, forgetting its structure. π[_] : Algebra Ξ± Ο β Type Ξ± π[ π¨ ] = Setoid.Carrier π»[ π¨ ]
We use the ascii symbol ^ to define an infix function for operation-symbol
interpretation in an algebra.1
-- Interpretation of an operation symbol in an algebra. _^_ : (f : OperationSymbolsOf π)(π¨ : Algebra Ξ± Ο) β Op (ArityOf π f) π[ π¨ ] f ^ π¨ = Ξ» a β (Interp π¨) β¨$β© (f , a)
We previously used a unicode symbol for this purpose; the definition is preserved for backward compatibility, but its use is deprecated in favor of the ascii version above. See ADR-002 Β§7 for the rationale.
_Μ_ : (f : OperationSymbolsOf π)(π¨ : Algebra Ξ± Ο) β Op (ArityOf π f) π[ π¨ ] f Μ π¨ = Ξ» a β (Interp π¨) β¨$β© (f , a) {-# WARNING_ON_USAGE _Μ_ "The combining-caret notation `_Μ_` is deprecated as of v3.0 and will be removed in v3.1. Use the ASCII `_^_` defined immediately above. See ADR-002 Β§7." #-}
Smart constructors for concrete algebras¶
Authoring a concrete Algebra by hand means supplying the
Interp field as a Func (β¨ π β© Domain) Domain, whose
congruence proof must take apart the Ξ£/EqArgs encoding of β¨ π β©:
the clause βcong {o , _} {.o , _} (refl , argsβ) = β¦ recurs verbatim in every such
algebra (it appears across Examples.Setoid.* and Classical.Bundles.*). The two
builders below package that destructuring once.
A fully automatic congruence is not derivable at this layer, and deliberately so.
Passing from the pointwise hypothesis β i β u i β v i to f o u β f o v is exactly an
application of function extensionality, which the Setoid development avoids on principle
and which is in any case unavailable under --safe --cubical-compatible.
So each constructor still requires a per-operation, pointwise congruence cong-f;
it removes only the (refl , argsβ) boilerplate, never the mathematical content.
mkAlgebra is the general builder. Given a carrier setoid π, an
interpretation f of each operation symbol, and a proof cong-f that every f o
respects pointwise setoid equality of its argument tuple, mkAlgebra
assembles the Algebra, discharging the
{o , _} {.o , _} (refl , argsβ) match internally.
module _ (π· : Setoid Ξ± Ο) where open Setoid π· using (_β_) renaming (Carrier to D) mkAlgebra : (f : (o : OperationSymbolsOf π) β Op (ArityOf π o) D) β (β o β {u v : ArityOf π o β D} β (β i β u i β v i) β f o u β f o v) β Algebra Ξ± Ο mkAlgebra f cong-f .Domain = π· mkAlgebra f cong-f .Interp β¨$β© (o , args) = f o args mkAlgebra f cong-f .Interp .βcong {o , _} {.o , _} (refl , argsβ) = cong-f o argsβ
mkAlgebraβ specialises mkAlgebra to a carrier whose
equality is propositional _β‘_. It takes a bare type A, builds Domain = β‘.setoid A
(a Setoid Ξ± Ξ±, so the result is Algebra Ξ± Ξ±), and asks for cong-f in pointwise _β‘_
form β e.g. β‘.congβ for a binary operation, as in the ββΈ-magma of
Examples.Setoid.FreeMagma.
mkAlgebraβ : (A : Type Ξ±) (f : (o : OperationSymbolsOf π) β Op (ArityOf π o) A) β (β o β {u v : ArityOf π o β A} β (β i β u i β‘ v i) β f o u β‘ f o v) β Algebra Ξ± Ξ± mkAlgebraβ A f cong-f = mkAlgebra (β‘.setoid A) f cong-f
Sometimes we want to extract the universe level of a given algebra or its carrier. The following functions provide that information.
-- The universe level of an algebra Level-of-Alg : {Ξ± Ο π π₯ : Level}{π : Signature π π₯} β Algebra Ξ± Ο β Level Level-of-Alg {Ξ± = Ξ±}{Ο}{π}{π₯} _ = π β π₯ β lsuc (Ξ± β Ο) -- The universe level of the carrier of an algebra Level-of-Carrier : {Ξ± Ο π π₯ : Level}{π : Signature π π₯} β Algebra Ξ± Ο β Level Level-of-Carrier {Ξ± = Ξ±} _ = Ξ±
Level lifting setoid algebra types¶
module _ (π¨ : Algebra Ξ± Ο)(β : Level) where open Algebra π¨ using () renaming ( Domain to A ) open Setoid A using (sym ; trans ) renaming ( Carrier to β£Aβ£ ; _β_ to _ββ_ ; refl to reflβ ) open Level Lift-AlgΛ‘ : Algebra (Ξ± β β) Ο Lift-AlgΛ‘ .Domain = record { Carrier = Lift β β£Aβ£ ; _β_ = Ξ» x y β lower x ββ lower y ; isEquivalence = record { refl = reflβ ; sym = sym ; trans = trans } } Lift-AlgΛ‘ .Interp β¨$β© (f , la) = lift $ (f ^ π¨) (lower β la) Lift-AlgΛ‘ .Interp .βcong (refl , la=lb) = βcong (Interp π¨) (refl , la=lb) Lift-AlgΚ³ : Algebra Ξ± (Ο β β) Lift-AlgΚ³ .Domain = record { Carrier = β£Aβ£ ; _β_ = (Lift β) ββ _ββ_ ; isEquivalence = record { refl = lift reflβ ; sym = lift β sym β lower ; trans = Ξ» x y β lift $ trans (lower x) (lower y) } } Lift-AlgΚ³ .Interp β¨$β© (f , la) = (f ^ π¨) la Lift-AlgΚ³ .Interp .βcong (refl , laβ‘lb) = lift $ βcong (Interp π¨) (β‘.refl , (lower β laβ‘lb)) Lift-Alg : (π¨ : Algebra Ξ± Ο)(ββ ββ : Level) β Algebra (Ξ± β ββ) (Ο β ββ) Lift-Alg π¨ ββ = Lift-AlgΚ³ (Lift-AlgΛ‘ π¨ ββ)
-
The
_^_symbol is definitionally identical to_Μ_and was introduced for grep-friendliness and to survive shell-pipeline tooling. NewClassical/code uses_^_exclusively; existingSetoid/code may continue to use_Μ_until v3.1. See ADR-002 Β§7 for the rationale and per-tree policy. ↩