{-# OPTIONS --cubical --no-import-sorts --safe #-}
module Cubical.Algebra.Group.Base where
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.SIP
open import Cubical.Data.Sigma
open import Cubical.Data.Int renaming (_+_ to _+Int_ ; _-_ to _-Int_; -_ to -Int_)
open import Cubical.Data.Unit
open import Cubical.Data.Bool
open import Cubical.Algebra.Monoid
open import Cubical.Algebra.Semigroup
open import Cubical.Foundations.HLevels
private
variable
ℓ : Level
record IsGroup {G : Type ℓ}
(0g : G) (_+_ : G → G → G) (-_ : G → G) : Type ℓ where
constructor isgroup
field
isMonoid : IsMonoid 0g _+_
inverse : (x : G) → (x + (- x) ≡ 0g) × ((- x) + x ≡ 0g)
open IsMonoid isMonoid public
infixl 6 _-_
_-_ : G → G → G
x - y = x + (- y)
invl : (x : G) → (- x) + x ≡ 0g
invl x = inverse x .snd
invr : (x : G) → x + (- x) ≡ 0g
invr x = inverse x .fst
record GroupStr (G : Type ℓ) : Type (ℓ-suc ℓ) where
constructor groupstr
field
0g : G
_+_ : G → G → G
-_ : G → G
isGroup : IsGroup 0g _+_ -_
infix 8 -_
infixr 7 _+_
open IsGroup isGroup public
Group : Type (ℓ-suc ℓ)
Group = TypeWithStr _ GroupStr
Group₀ : Type₁
Group₀ = Group {ℓ-zero}
group : (G : Type ℓ) (0g : G) (_+_ : G → G → G) (-_ : G → G) (h : IsGroup 0g _+_ -_) → Group
group G 0g _+_ -_ h = G , groupstr 0g _+_ -_ h
isSetGroup : (G : Group {ℓ}) → isSet ⟨ G ⟩
isSetGroup G = GroupStr.isGroup (snd G) .IsGroup.isMonoid .IsMonoid.isSemigroup .IsSemigroup.is-set
makeIsGroup : {G : Type ℓ} {0g : G} {_+_ : G → G → G} { -_ : G → G}
(is-setG : isSet G)
(assoc : (x y z : G) → x + (y + z) ≡ (x + y) + z)
(rid : (x : G) → x + 0g ≡ x)
(lid : (x : G) → 0g + x ≡ x)
(rinv : (x : G) → x + (- x) ≡ 0g)
(linv : (x : G) → (- x) + x ≡ 0g)
→ IsGroup 0g _+_ -_
IsGroup.isMonoid (makeIsGroup is-setG assoc rid lid rinv linv) = makeIsMonoid is-setG assoc rid lid
IsGroup.inverse (makeIsGroup is-setG assoc rid lid rinv linv) = λ x → rinv x , linv x
makeGroup : {G : Type ℓ} (0g : G) (_+_ : G → G → G) (-_ : G → G)
(is-setG : isSet G)
(assoc : (x y z : G) → x + (y + z) ≡ (x + y) + z)
(rid : (x : G) → x + 0g ≡ x)
(lid : (x : G) → 0g + x ≡ x)
(rinv : (x : G) → x + (- x) ≡ 0g)
(linv : (x : G) → (- x) + x ≡ 0g)
→ Group
makeGroup 0g _+_ -_ is-setG assoc rid lid rinv linv = _ , helper
where
helper : GroupStr _
GroupStr.0g helper = 0g
GroupStr._+_ helper = _+_
GroupStr.- helper = -_
GroupStr.isGroup helper = makeIsGroup is-setG assoc rid lid rinv linv
makeGroup-right : ∀ {ℓ} {A : Type ℓ}
→ (id : A)
→ (comp : A → A → A)
→ (inv : A → A)
→ (set : isSet A)
→ (assoc : ∀ a b c → comp a (comp b c) ≡ comp (comp a b) c)
→ (rUnit : ∀ a → comp a id ≡ a)
→ (rCancel : ∀ a → comp a (inv a) ≡ id)
→ Group
makeGroup-right id comp inv set assoc rUnit rCancel =
makeGroup id comp inv set assoc rUnit lUnit rCancel lCancel
where
_⨀_ = comp
abstract
lCancel : ∀ a → comp (inv a) a ≡ id
lCancel a =
inv a ⨀ a
≡⟨ sym (rUnit (comp (inv a) a)) ⟩
(inv a ⨀ a) ⨀ id
≡⟨ cong (comp (comp (inv a) a)) (sym (rCancel (inv a))) ⟩
(inv a ⨀ a) ⨀ (inv a ⨀ (inv (inv a)))
≡⟨ assoc _ _ _ ⟩
((inv a ⨀ a) ⨀ (inv a)) ⨀ (inv (inv a))
≡⟨ cong (λ □ → □ ⨀ _) (sym (assoc _ _ _)) ⟩
(inv a ⨀ (a ⨀ inv a)) ⨀ (inv (inv a))
≡⟨ cong (λ □ → (inv a ⨀ □) ⨀ (inv (inv a))) (rCancel a) ⟩
(inv a ⨀ id) ⨀ (inv (inv a))
≡⟨ cong (λ □ → □ ⨀ (inv (inv a))) (rUnit (inv a)) ⟩
inv a ⨀ (inv (inv a))
≡⟨ rCancel (inv a) ⟩
id
∎
lUnit : ∀ a → comp id a ≡ a
lUnit a =
id ⨀ a
≡⟨ cong (λ b → comp b a) (sym (rCancel a)) ⟩
(a ⨀ inv a) ⨀ a
≡⟨ sym (assoc _ _ _) ⟩
a ⨀ (inv a ⨀ a)
≡⟨ cong (comp a) (lCancel a) ⟩
a ⨀ id
≡⟨ rUnit a ⟩
a
∎
makeGroup-left : ∀ {ℓ} {A : Type ℓ}
→ (id : A)
→ (comp : A → A → A)
→ (inv : A → A)
→ (set : isSet A)
→ (assoc : ∀ a b c → comp a (comp b c) ≡ comp (comp a b) c)
→ (lUnit : ∀ a → comp id a ≡ a)
→ (lCancel : ∀ a → comp (inv a) a ≡ id)
→ Group
makeGroup-left id comp inv set assoc lUnit lCancel =
makeGroup id comp inv set assoc rUnit lUnit rCancel lCancel
where
abstract
rCancel : ∀ a → comp a (inv a) ≡ id
rCancel a =
comp a (inv a)
≡⟨ sym (lUnit (comp a (inv a))) ⟩
comp id (comp a (inv a))
≡⟨ cong (λ b → comp b (comp a (inv a))) (sym (lCancel (inv a))) ⟩
comp (comp (inv (inv a)) (inv a)) (comp a (inv a))
≡⟨ sym (assoc (inv (inv a)) (inv a) (comp a (inv a))) ⟩
comp (inv (inv a)) (comp (inv a) (comp a (inv a)))
≡⟨ cong (comp (inv (inv a))) (assoc (inv a) a (inv a)) ⟩
comp (inv (inv a)) (comp (comp (inv a) a) (inv a))
≡⟨ cong (λ b → comp (inv (inv a)) (comp b (inv a))) (lCancel a) ⟩
comp (inv (inv a)) (comp id (inv a))
≡⟨ cong (comp (inv (inv a))) (lUnit (inv a)) ⟩
comp (inv (inv a)) (inv a)
≡⟨ lCancel (inv a) ⟩
id
∎
rUnit : ∀ a → comp a id ≡ a
rUnit a =
comp a id
≡⟨ cong (comp a) (sym (lCancel a)) ⟩
comp a (comp (inv a) a)
≡⟨ assoc a (inv a) a ⟩
comp (comp a (inv a)) a
≡⟨ cong (λ b → comp b a) (rCancel a) ⟩
comp id a
≡⟨ lUnit a ⟩
a
∎
open GroupStr hiding (0g ; _+_ ; -_)
isSetCarrier : ∀ {ℓ} → (G : Group {ℓ}) → isSet ⟨ G ⟩
isSetCarrier G = IsSemigroup.is-set (IsMonoid.isSemigroup (GroupStr.isMonoid (snd G)))
open GroupStr
dirProd : ∀ {ℓ ℓ'} → Group {ℓ} → Group {ℓ'} → Group
fst (dirProd G H) = fst G × fst H
0g (snd (dirProd G H)) = (0g (snd G)) , (0g (snd H))
_+_ (snd (dirProd G H)) x y = _+_ (snd G) (fst x) (fst y)
, _+_ (snd H) (snd x) (snd y)
(- snd (dirProd G H)) x = (-_ (snd G) (fst x)) , (-_ (snd H) (snd x))
IsSemigroup.is-set (IsMonoid.isSemigroup (IsGroup.isMonoid (isGroup (snd (dirProd G H))))) =
isSet× (is-set (snd G)) (is-set (snd H))
IsSemigroup.assoc (IsMonoid.isSemigroup (IsGroup.isMonoid (isGroup (snd (dirProd G H))))) x y z i =
assoc (snd G) (fst x) (fst y) (fst z) i , assoc (snd H) (snd x) (snd y) (snd z) i
fst (IsMonoid.identity (IsGroup.isMonoid (isGroup (snd (dirProd G H)))) x) i =
rid (snd G) (fst x) i , rid (snd H) (snd x) i
snd (IsMonoid.identity (IsGroup.isMonoid (isGroup (snd (dirProd G H)))) x) i =
lid (snd G) (fst x) i , lid (snd H) (snd x) i
fst (IsGroup.inverse (isGroup (snd (dirProd G H))) x) i =
(invr (snd G) (fst x) i) , invr (snd H) (snd x) i
snd (IsGroup.inverse (isGroup (snd (dirProd G H))) x) i =
(invl (snd G) (fst x) i) , invl (snd H) (snd x) i
trivialGroup : Group₀
trivialGroup = Unit , groupstr tt (λ _ _ → tt) (λ _ → tt)
(makeIsGroup isSetUnit (λ _ _ _ → refl) (λ _ → refl) (λ _ → refl)
(λ _ → refl) (λ _ → refl))
intGroup : Group₀
fst intGroup = Int
0g (snd intGroup) = 0
_+_ (snd intGroup) = _+Int_
- snd intGroup = _-Int_ 0
isGroup (snd intGroup) = isGroupInt
where
abstract
isGroupInt : IsGroup (pos 0) _+Int_ (_-Int_ (pos 0))
isGroupInt = makeIsGroup isSetInt +-assoc (λ x → refl) (λ x → +-comm 0 x)
(λ x → +-comm x (pos 0 -Int x) ∙ minusPlus x 0) (λ x → minusPlus x 0)
open IsGroup
open IsMonoid
open IsSemigroup renaming (assoc to assoc')
BoolGroup : Group₀
fst BoolGroup = Bool
0g (snd BoolGroup) = true
(snd BoolGroup GroupStr.+ false) false = true
(snd BoolGroup GroupStr.+ false) true = false
(snd BoolGroup GroupStr.+ true) y = y
(- snd BoolGroup) false = false
(- snd BoolGroup) true = true
is-set (isSemigroup (isMonoid (isGroup (snd BoolGroup)))) = isSetBool
assoc' (isSemigroup (isMonoid (isGroup (snd BoolGroup)))) false false false = refl
assoc' (isSemigroup (isMonoid (isGroup (snd BoolGroup)))) false false true = refl
assoc' (isSemigroup (isMonoid (isGroup (snd BoolGroup)))) false true false = refl
assoc' (isSemigroup (isMonoid (isGroup (snd BoolGroup)))) false true true = refl
assoc' (isSemigroup (isMonoid (isGroup (snd BoolGroup)))) true false false = refl
assoc' (isSemigroup (isMonoid (isGroup (snd BoolGroup)))) true false true = refl
assoc' (isSemigroup (isMonoid (isGroup (snd BoolGroup)))) true true false = refl
assoc' (isSemigroup (isMonoid (isGroup (snd BoolGroup)))) true true true = refl
identity (IsGroup.isMonoid (isGroup (snd BoolGroup))) false = refl , refl
identity (IsGroup.isMonoid (isGroup (snd BoolGroup))) true = refl , refl
inverse (isGroup (snd BoolGroup)) false = refl , refl
inverse (isGroup (snd BoolGroup)) true = refl , refl