open import GpdCont.Prelude
module GpdCont.Group.Pi (ℓ : Level) where
open import GpdCont.HomotopySet
open import GpdCont.Equiv using (isSet→section-equivToIso)
open import Cubical.Foundations.Equiv
open import Cubical.Foundations.Isomorphism
open import Cubical.Foundations.HLevels
open import Cubical.Data.Sigma
open import Cubical.Categories.Category.Base
open import Cubical.Categories.Instances.Groups
open import Cubical.Categories.Adjoint.UniversalElements
open import Cubical.Categories.Presheaf.Representable
open import Cubical.Algebra.Group.Base
open import Cubical.Algebra.Group.Morphisms
open import Cubical.Algebra.Group.MorphismProperties
open import Cubical.Algebra.Group.Instances.Pi using (ΠGroup)
private
module Group = Category (GroupCategory {ℓ})
module _ (K : hSet ℓ) (G : ⟨ K ⟩ → Group.ob) where
open import GpdCont.Categories.Products (GroupCategory {ℓ}) ℓ
private
Group→hSet : (H : Group.ob) → hSet ℓ
Group→hSet H .fst = ⟨ H ⟩
Group→hSet H .snd = str H .GroupStr.is-set
Π : Group.ob
Π = ΠGroup G
proj : ∀ k → Group.Hom[ Π , G k ]
proj k .fst φ = φ k
proj k .snd .IsGroupHom.pres· φ ψ = refl
proj k .snd .IsGroupHom.pres1 = refl
proj k .snd .IsGroupHom.presinv φ = refl
univ-iso : (H : Group.ob) → Iso Group.Hom[ H , Π ] (∀ k → Group.Hom[ H , G k ])
univ-iso H =
Group.Hom[ H , Π ] Iso⟨⟩
Σ[ φ ∈ (⟨ H ⟩ → (k : ⟨ K ⟩) → ⟨ G k ⟩) ] IsGroupHom (str H) φ (str Π) Iso⟨ Σ-cong-iso-fst flipIso ⟩
Σ[ φ ∈ ((k : ⟨ K ⟩) → ⟨ H ⟩ → ⟨ G k ⟩) ] IsGroupHom (str H) (flip φ) (str Π) Iso⟨ Σ-cong-iso-snd is-group-hom-iso ⟩
Σ[ φ ∈ ((k : ⟨ K ⟩) → ⟨ H ⟩ → ⟨ G k ⟩) ] (∀ k → IsGroupHom (str H) (φ k) (str (G k))) Iso⟨ invIso Σ-Π-Iso ⟩
(∀ k → Group.Hom[ H , G k ]) Iso∎
where
is-group-hom-iso : (φ : (k : ⟨ K ⟩) → ⟨ H ⟩ → ⟨ G k ⟩)
→ Iso
(IsGroupHom (str H) (flip φ) (str Π))
(∀ k → IsGroupHom (str H) (φ k) (str (G k)))
is-group-hom-iso φ = isProp→Iso
(isPropIsGroupHom _ _)
(isPropΠ λ k → isPropIsGroupHom _ _)
(λ where
φ*-hom k .IsGroupHom.pres· g h → φ*-hom .IsGroupHom.pres· g h ≡$ k
φ*-hom k .IsGroupHom.presinv g → φ*-hom .IsGroupHom.presinv g ≡$ k
φ*-hom k .IsGroupHom.pres1 → φ*-hom .IsGroupHom.pres1 ≡$ k
)
(λ where
φ-hom .IsGroupHom.pres· g h → funExt (λ k → φ-hom k .IsGroupHom.pres· g h)
φ-hom .IsGroupHom.presinv g → funExt (λ k → φ-hom k .IsGroupHom.presinv g)
φ-hom .IsGroupHom.pres1 → funExt (λ k → φ-hom k .IsGroupHom.pres1)
)
private module _ (H : Group.ob) where
univ-fun : Group.Hom[ H , Π ] → (∀ k → Group.Hom[ H , G k ])
univ-fun φ = λ k → φ Group.⋆ (proj k)
univ-equiv' : Group.Hom[ H , Π ] ≃ (∀ k → Group.Hom[ H , G k ])
univ-equiv' = isoToEquiv (univ-iso H)
univ-fun≡ : equivFun univ-equiv' ≡ univ-fun
univ-fun≡ = funExt λ φ → funExt λ k → GroupHom≡ refl
is-univ : isEquiv univ-fun
is-univ = subst {x = equivFun univ-equiv'} {y = univ-fun} isEquiv univ-fun≡ (equivIsEquiv univ-equiv')
univ-equiv : Group.Hom[ H , Π ] ≃ (∀ k → Group.Hom[ H , G k ])
univ-equiv .fst = _
univ-equiv .snd = is-univ
univ-equiv≡ : univ-equiv' ≡ univ-equiv
univ-equiv≡ = equivEq univ-fun≡
GroupProduct : Product K G
GroupProduct .UniversalElement.vertex = ΠGroup G
GroupProduct .UniversalElement.element = proj
GroupProduct .UniversalElement.universal = is-univ
module _ (H : Group.ob) where
opaque
univ-coherence : NotationAt.univ-iso K G GroupProduct H ≡ univ-iso H
univ-coherence =
equivToIso (univ-equiv H) ≡⟨ cong equivToIso (sym (univ-equiv≡ H)) ⟩
equivToIso (isoToEquiv (univ-iso H)) ≡⟨ isSet→section-equivToIso Group.isSetHom (isSetΠ (λ k → Group.isSetHom)) (univ-iso H) ⟩
univ-iso H ∎
univ-inv-coherence : Iso.inv (NotationAt.univ-iso K G GroupProduct H) ≡ univ-iso H .Iso.inv
univ-inv-coherence = cong Iso.inv univ-coherence
GroupProducts = GroupProduct