module Cubical.Algebra.Monoid.Base where
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.Isomorphism
open import Cubical.Foundations.Equiv
open import Cubical.Foundations.HLevels
open import Cubical.Foundations.SIP
open import Cubical.Data.Sigma
open import Cubical.Algebra.Semigroup
open import Cubical.Displayed.Base
open import Cubical.Displayed.Auto
open import Cubical.Displayed.Record
open import Cubical.Displayed.Universe
open import Cubical.Reflection.RecordEquiv
open Iso
private
variable
ℓ ℓ' : Level
record IsMonoid {A : Type ℓ} (ε : A) (_·_ : A → A → A) : Type ℓ where
constructor ismonoid
field
isSemigroup : IsSemigroup _·_
·IdR : (x : A) → x · ε ≡ x
·IdL : (x : A) → ε · x ≡ x
open IsSemigroup isSemigroup public
unquoteDecl IsMonoidIsoΣ = declareRecordIsoΣ IsMonoidIsoΣ (quote IsMonoid)
record MonoidStr (A : Type ℓ) : Type ℓ where
constructor monoidstr
field
ε : A
_·_ : A → A → A
isMonoid : IsMonoid ε _·_
infixl 7 _·_
open IsMonoid isMonoid public
Monoid : ∀ ℓ → Type (ℓ-suc ℓ)
Monoid ℓ = TypeWithStr ℓ MonoidStr
monoid : (A : Type ℓ) (ε : A) (_·_ : A → A → A) (h : IsMonoid ε _·_) → Monoid ℓ
monoid A ε _·_ h = A , monoidstr ε _·_ h
-- Easier to use constructors
makeIsMonoid : {M : Type ℓ} {ε : M} {_·_ : M → M → M}
(is-setM : isSet M)
(·Assoc : (x y z : M) → x · (y · z) ≡ (x · y) · z)
(·IdR : (x : M) → x · ε ≡ x)
(·IdL : (x : M) → ε · x ≡ x)
→ IsMonoid ε _·_
IsMonoid.isSemigroup (makeIsMonoid is-setM ·Assoc ·IdR ·IdL) = issemigroup is-setM ·Assoc
IsMonoid.·IdR (makeIsMonoid is-setM ·Assoc ·IdR ·IdL) = ·IdR
IsMonoid.·IdL (makeIsMonoid is-setM ·Assoc ·IdR ·IdL) = ·IdL
makeMonoid : {M : Type ℓ} (ε : M) (_·_ : M → M → M)
(is-setM : isSet M)
(·Assoc : (x y z : M) → x · (y · z) ≡ (x · y) · z)
(·IdR : (x : M) → x · ε ≡ x)
(·IdL : (x : M) → ε · x ≡ x)
→ Monoid ℓ
makeMonoid ε _·_ is-setM ·Assoc ·IdR ·IdL =
monoid _ ε _·_ (makeIsMonoid is-setM ·Assoc ·IdR ·IdL)
record IsMonoidHom {A : Type ℓ} {B : Type ℓ'}
(M : MonoidStr A) (f : A → B) (N : MonoidStr B)
: Type (ℓ-max ℓ ℓ')
where
constructor monoidequiv
-- Shorter qualified names
private
module M = MonoidStr M
module N = MonoidStr N
field
presε : f M.ε ≡ N.ε
pres· : (x y : A) → f (x M.· y) ≡ f x N.· f y
MonoidHom : (L : Monoid ℓ) (M : Monoid ℓ') → Type (ℓ-max ℓ ℓ')
MonoidHom L M = Σ[ f ∈ (⟨ L ⟩ → ⟨ M ⟩) ] IsMonoidHom (L .snd) f (M .snd)
IsMonoidEquiv : {A : Type ℓ} {B : Type ℓ'} (M : MonoidStr A) (e : A ≃ B) (N : MonoidStr B)
→ Type (ℓ-max ℓ ℓ')
IsMonoidEquiv M e N = IsMonoidHom M (e .fst) N
MonoidEquiv : (M : Monoid ℓ) (N : Monoid ℓ') → Type (ℓ-max ℓ ℓ')
MonoidEquiv M N = Σ[ e ∈ ⟨ M ⟩ ≃ ⟨ N ⟩ ] IsMonoidEquiv (M .snd) e (N .snd)
-- We now extract the important results from the above module
isPropIsMonoid : {M : Type ℓ} (ε : M) (_·_ : M → M → M) → isProp (IsMonoid ε _·_)
isPropIsMonoid ε _·_ =
isOfHLevelRetractFromIso 1 IsMonoidIsoΣ
(isPropΣ (isPropIsSemigroup _·_)
(λ semi → isProp× (isPropΠ (λ _ → is-set semi _ _))
(isPropΠ (λ _ → is-set semi _ _))))
where
open IsSemigroup
𝒮ᴰ-Monoid : DUARel (𝒮-Univ ℓ) MonoidStr ℓ
𝒮ᴰ-Monoid =
𝒮ᴰ-Record (𝒮-Univ _) IsMonoidEquiv
(fields:
data[ ε ∣ autoDUARel _ _ ∣ presε ]
data[ _·_ ∣ autoDUARel _ _ ∣ pres· ]
prop[ isMonoid ∣ (λ _ _ → isPropIsMonoid _ _) ])
where
open MonoidStr
open IsMonoidHom
MonoidPath : (M N : Monoid ℓ) → MonoidEquiv M N ≃ (M ≡ N)
MonoidPath = ∫ 𝒮ᴰ-Monoid .UARel.ua
module MonoidTheory {ℓ} (M : Monoid ℓ) where
open MonoidStr (snd M)
-- Added for its use in groups
-- If there exists a inverse of an element it is unique
inv-lemma : (x y z : ⟨ M ⟩) → y · x ≡ ε → x · z ≡ ε → y ≡ z
inv-lemma x y z left-inverse right-inverse =
y ≡⟨ sym (·IdR y) ⟩
y · ε ≡⟨ congR _·_ (sym right-inverse) ⟩
y · (x · z) ≡⟨ ·Assoc y x z ⟩
(y · x) · z ≡⟨ congL _·_ left-inverse ⟩
ε · z ≡⟨ ·IdL z ⟩
z ∎
-- Added for its use in division rings
hasInverse : (x : ⟨ M ⟩) → Type ℓ
hasInverse x = Σ[ -x ∈ ⟨ M ⟩ ] (-x · x ≡ ε) × (x · -x ≡ ε)
isPropHasInverse : ∀ x → isProp (hasInverse x)
isPropHasInverse x (y , invly , _) (z , _ , invrz)
= Σ≡Prop (λ a → isProp× (is-set (a · x) ε)
(is-set (x · a) ε))
(inv-lemma x y z invly invrz)