{-# OPTIONS --lossy-unification #-}
module GpdCont.GroupAction.Delooping where
open import GpdCont.Prelude
open import GpdCont.Univalence using (ua ; ua→)
open import GpdCont.Connectivity using (isPathConnected)
open import GpdCont.GroupAction.Base using (Action ; _⁺_ ; module ActionProperties)
open import GpdCont.GroupAction.Equivariant renaming (isEquivariantMap[_][_,_] to isEquivariantMap)
open import GpdCont.GroupAction.TwoCategory using (GroupActionᴰ ; GroupAction)
open import GpdCont.GroupAction.AssociatedBundle using (associatedBundle ; associatedBundleMap ; associatedBundleMapEquiv)
open import GpdCont.Group.TwoCategory using (TwoGroup)
open import GpdCont.SetBundle.Base using (SetBundle ; SetBundleᴰ ; SetBundleᵀ ; isLocallyGroupoidalSetBundle ; module SetBundleNotation)
import GpdCont.Delooping as Delooping
open import GpdCont.Delooping.Functor using (module TwoFunc ; module LocalInverse)
import GpdCont.Delooping.Map as DeloopingMap
open import GpdCont.TwoCategory.Base using (TwoCategory)
open import GpdCont.TwoCategory.StrictFunctor using (StrictFunctor)
open import GpdCont.TwoCategory.StrictFunctor.LocalFunctor as LocalFunctor using (LocalFunctor)
open import GpdCont.TwoCategory.LocalCategory using (LocalCategory)
open import GpdCont.TwoCategory.Displayed.Base using (TwoCategoryᴰ)
open import GpdCont.TwoCategory.Displayed.StrictFunctor using (StrictFunctorᴰ)
open import GpdCont.TwoCategory.Displayed.LocallyThin using (IntoLocallyThin)
open import GpdCont.TwoCategory.HomotopyGroupoid using (hGpdCat)
open import Cubical.Foundations.Equiv as Equiv using (isEquiv ; equivFun ; equivIsEquiv ; fiber ; invEq ; _∙ₑ_)
open import Cubical.Foundations.HLevels using (isOfHLevelPathP' ; isSet→ ; isSet→SquareP)
open import Cubical.Foundations.Path using (compPath→Square)
open import Cubical.Foundations.Transport using (subst⁻ ; subst⁻-filler ; substCommSlice)
open import Cubical.Functions.FunExtEquiv using (funExtEquiv ; funExtDep)
import Cubical.Data.Sigma as Sigma
open import Cubical.Algebra.Group.MorphismProperties using (GroupHom≡)
{-# INJECTIVE_FOR_INFERENCE ⟨_⟩ #-}
module _ (ℓ : Level) where
private
module Group = TwoCategory (TwoGroup ℓ)
module GroupAction = TwoCategory (GroupAction ℓ)
module GroupActionᴰ = TwoCategoryᴰ (GroupActionᴰ ℓ)
module hGpdCat = TwoCategory (hGpdCat ℓ)
module SetBundle = SetBundleNotation ℓ
open Delooping.𝔹 using (⋆ ; loop)
𝔹 = TwoFunc.𝔹 ℓ
module 𝔹 = StrictFunctor 𝔹
𝔹ᴰ₀ : ∀ {G} → GroupActionᴰ.ob[ G ] → SetBundle.ob[ 𝔹.₀ G ]
𝔹ᴰ₀ (X , σ) = associatedBundle {X = X} σ
{-# INJECTIVE_FOR_INFERENCE 𝔹ᴰ₀ #-}
𝔹ᴰ₁-equiv : ∀ {G H} {φ : Group.hom G H} {Xᴳ : GroupActionᴰ.ob[ G ]} {Yᴴ : GroupActionᴰ.ob[ H ]}
→ GroupActionᴰ.hom[ φ ] Xᴳ Yᴴ ≃ SetBundle.hom[ 𝔹.₁ φ ] (𝔹ᴰ₀ Xᴳ) (𝔹ᴰ₀ Yᴴ)
𝔹ᴰ₁-equiv {φ} {Xᴳ = _ , σ} {Yᴴ = _ , τ} = associatedBundleMapEquiv σ τ φ
private
𝔹ᴰ₁ : ∀ {G H} {φ : Group.hom G H} {Xᴳ : GroupActionᴰ.ob[ G ]} {Yᴴ : GroupActionᴰ.ob[ H ]}
→ GroupActionᴰ.hom[ φ ] Xᴳ Yᴴ
→ SetBundle.hom[ 𝔹.₁ φ ] (𝔹ᴰ₀ Xᴳ) (𝔹ᴰ₀ Yᴴ)
𝔹ᴰ₁ = equivFun 𝔹ᴰ₁-equiv
{-# INJECTIVE_FOR_INFERENCE 𝔹ᴰ₁ #-}
𝔹ᴰ₁⁻¹ : ∀ {G H} {φ : Group.hom G H} {Xᴳ : GroupActionᴰ.ob[ G ]} {Yᴴ : GroupActionᴰ.ob[ H ]}
→ SetBundle.hom[ 𝔹.₁ φ ] (𝔹ᴰ₀ Xᴳ) (𝔹ᴰ₀ Yᴴ)
→ GroupActionᴰ.hom[ φ ] Xᴳ Yᴴ
𝔹ᴰ₁⁻¹ = invEq 𝔹ᴰ₁-equiv
isEquiv-𝔹ᴰ₁ : ∀ {G H} {φ : Group.hom G H} {Xᴳ : GroupActionᴰ.ob[ G ]} {Yᴴ : GroupActionᴰ.ob[ H ]}
→ isEquiv (𝔹ᴰ₁ {G} {H} {φ} {Xᴳ} {Yᴴ})
isEquiv-𝔹ᴰ₁ = equivIsEquiv 𝔹ᴰ₁-equiv
private
module _
{G} {Y} {f g : hGpdCat.hom (𝔹.₀ G) Y} {r : hGpdCat.rel f g}
{Xᴳ : GroupActionᴰ.ob[ G ]}
(yᴰ : SetBundle.ob[ Y ])
{fᴰ : SetBundle.hom[ f ] (𝔹ᴰ₀ Xᴳ) yᴰ}
{gᴰ : SetBundle.hom[ g ] (𝔹ᴰ₀ Xᴳ) yᴰ}
where
open Delooping G using (elimPropEquiv)
opaque
isProp𝔹ᴰ₁PathP : ∀ x → isProp (PathP (λ i → ⟨ yᴰ (r i x) ⟩ → ⟨ 𝔹ᴰ₀ Xᴳ x ⟩) (fᴰ x) (gᴰ x))
isProp𝔹ᴰ₁PathP x = isOfHLevelPathP' 1 (isSet→ is-set-𝔹ᴰ₀) _ _ where
is-set-𝔹ᴰ₀ : isSet ⟨ 𝔹ᴰ₀ Xᴳ x ⟩
is-set-𝔹ᴰ₀ = str $ 𝔹ᴰ₀ Xᴳ x
𝔹ᴰ₁-PathPEquiv :
(PathP (λ i → ⟨ yᴰ (r i ⋆) ⟩ → ⟨ 𝔹ᴰ₀ Xᴳ ⋆ ⟩) (fᴰ ⋆) (gᴰ ⋆))
≃
(∀ x → PathP (λ i → ⟨ yᴰ (r i x) ⟩ → ⟨ 𝔹ᴰ₀ Xᴳ x ⟩) (fᴰ x) (gᴰ x))
𝔹ᴰ₁-PathPEquiv = elimPropEquiv isProp𝔹ᴰ₁PathP
𝔹ᴰ₁-PathP≃SetBundleRel : (PathP (λ i → ⟨ yᴰ (r i ⋆) ⟩ → ⟨ 𝔹ᴰ₀ Xᴳ ⋆ ⟩) (fᴰ ⋆) (gᴰ ⋆)) ≃ (SetBundle.rel[_] {yᴰ = yᴰ} r fᴰ gᴰ)
𝔹ᴰ₁-PathP≃SetBundleRel = 𝔹ᴰ₁-PathPEquiv ∙ₑ funExtEquiv
{-# INJECTIVE_FOR_INFERENCE 𝔹ᴰ₁-PathP≃SetBundleRel #-}
𝔹ᴰ₁PathP : (p⋆ : PathP (λ i → ⟨ yᴰ (r i ⋆) ⟩ → ⟨ 𝔹ᴰ₀ Xᴳ ⋆ ⟩) (fᴰ ⋆) (gᴰ ⋆))
→ SetBundle.rel[_] {yᴰ = yᴰ} r fᴰ gᴰ
𝔹ᴰ₁PathP = equivFun 𝔹ᴰ₁-PathP≃SetBundleRel
module _
{G H} {φ ψ : Group.hom G H}
{r : Group.rel φ ψ}
{Xᴳ : GroupActionᴰ.ob[ G ]}
{Yᴴ @ (Y , τ) : GroupActionᴰ.ob[ H ]}
{fᴰ @ (f , _) : GroupActionᴰ.hom[ φ ] Xᴳ Yᴴ}
{gᴰ @ (g , _) : GroupActionᴰ.hom[ ψ ] Xᴳ Yᴴ}
where
𝔹ᴰ₂-equiv : (GroupActionᴰ.rel[ r ] fᴰ gᴰ) ≃ (SetBundle.rel[_] {yᴰ = 𝔹ᴰ₀ Yᴴ} (𝔹.₂ {f = φ} {g = ψ} r) (𝔹ᴰ₁ fᴰ) (𝔹ᴰ₁ gᴰ))
𝔹ᴰ₂-equiv =
(GroupActionᴰ.rel[ r ] fᴰ gᴰ) ≃⟨ ActionProperties.uaExtEquiv τ {f₀ = f} {f₁ = g} (r .fst) ⟩
(PathP (λ i → ⟨ 𝔹ᴰ₀ {H} Yᴴ (𝔹.₂ {f = φ} {g = ψ} r i ⋆) ⟩ → ⟨ 𝔹ᴰ₀ {G} Xᴳ ⋆ ⟩) f g) ≃⟨ 𝔹ᴰ₁-PathP≃SetBundleRel {f = 𝔹.₁ φ} {g = 𝔹.₁ ψ} {r = 𝔹.₂ r} (𝔹ᴰ₀ Yᴴ) ⟩
(SetBundle.rel[_] {yᴰ = 𝔹ᴰ₀ Yᴴ} (𝔹.₂ r) (𝔹ᴰ₁ fᴰ) (𝔹ᴰ₁ gᴰ)) ≃∎
𝔹ᴰ₂ : GroupActionᴰ.rel[ r ] fᴰ gᴰ → SetBundle.rel[_] {yᴰ = 𝔹ᴰ₀ Yᴴ} (𝔹.₂ {f = φ} {g = ψ} r) (𝔹ᴰ₁ fᴰ) (𝔹ᴰ₁ gᴰ)
𝔹ᴰ₂ = equivFun 𝔹ᴰ₂-equiv
{-# INJECTIVE_FOR_INFERENCE 𝔹ᴰ₂ #-}
isEquiv-𝔹ᴰ₂ : isEquiv 𝔹ᴰ₂
isEquiv-𝔹ᴰ₂ = equivIsEquiv 𝔹ᴰ₂-equiv
private
𝔹-rel-id : ∀ {x y : Group.ob} {f : Group.hom x y} {xᴰ : GroupActionᴰ.ob[ x ]} {yᴰ : GroupActionᴰ.ob[ y ]}
→ (fᴰ : GroupActionᴰ.hom[ f ] xᴰ yᴰ)
→ PathP (λ i → SetBundle.rel[_] {yᴰ = 𝔹ᴰ₀ yᴰ} (𝔹.F-rel-id {f = f} i) (𝔹ᴰ₁ fᴰ) (𝔹ᴰ₁ fᴰ))
(𝔹ᴰ₂ {r = Group.id-rel f} (GroupActionᴰ.id-relᴰ fᴰ))
(SetBundle.id-relᴰ {yᴰ = 𝔹ᴰ₀ yᴰ} (𝔹ᴰ₁ fᴰ))
𝔹-rel-id {f} {yᴰ} fᴰ = SetBundle.relᴰ≡ {yᴰ = 𝔹ᴰ₀ yᴰ} (𝔹.F-rel-id {f = f})
𝔹-rel-trans : ∀ {x y} {f g h : Group.hom x y} {r : Group.rel f g} {s : Group.rel g h}
→ {xᴰ : GroupActionᴰ.ob[ x ]} {yᴰ : GroupActionᴰ.ob[ y ]}
→ {fᴰ : GroupActionᴰ.hom[ f ] xᴰ yᴰ}
→ {gᴰ : GroupActionᴰ.hom[ g ] xᴰ yᴰ}
→ {hᴰ : GroupActionᴰ.hom[ h ] xᴰ yᴰ}
→ (rᴰ : GroupActionᴰ.rel[ r ] fᴰ gᴰ)
→ (sᴰ : GroupActionᴰ.rel[ s ] gᴰ hᴰ)
→ PathP (λ i → SetBundle.rel[_] {yᴰ = 𝔹ᴰ₀ yᴰ} (𝔹.F-rel-trans r s i) (𝔹ᴰ₁ fᴰ) (𝔹ᴰ₁ hᴰ))
(𝔹ᴰ₂ (GroupActionᴰ.transᴰ {r = r} {s = s} {fᴰ = fᴰ} {gᴰ = gᴰ} {hᴰ = hᴰ} rᴰ sᴰ))
(SetBundle.transᴰ {yᴰ = 𝔹ᴰ₀ yᴰ} {gᴰ = 𝔹ᴰ₁ gᴰ} (𝔹ᴰ₂ rᴰ) (𝔹ᴰ₂ sᴰ))
𝔹-rel-trans {r} {s} {yᴰ} rᴰ sᴰ = SetBundle.relᴰ≡ {r = 𝔹.₂ (r Group.∙ᵥ s)} {s = 𝔹.₂ r hGpdCat.∙ᵥ 𝔹.₂ s} {yᴰ = 𝔹ᴰ₀ yᴰ} (𝔹.F-rel-trans r s)
𝔹-hom-comp : ∀ {x y z} {f : Group.hom x y} {g : Group.hom y z}
→ {xᴰ : GroupActionᴰ.ob[ x ]} {yᴰ : GroupActionᴰ.ob[ y ]} {zᴰ : GroupActionᴰ.ob[ z ]}
→ (fᴰ : GroupActionᴰ.hom[ f ] xᴰ yᴰ) (gᴰ : GroupActionᴰ.hom[ g ] yᴰ zᴰ)
→ PathP (λ i → SetBundle.hom[ 𝔹.F-hom-comp f g i ] (𝔹ᴰ₀ xᴰ) (𝔹ᴰ₀ zᴰ))
(SetBundle.comp-homᴰ {f = 𝔹.₁ f} {g = 𝔹.₁ g} {zᴰ = 𝔹ᴰ₀ zᴰ} (𝔹ᴰ₁ fᴰ) (𝔹ᴰ₁ gᴰ))
(𝔹ᴰ₁ (fᴰ GroupActionᴰ.∙₁ᴰ gᴰ))
𝔹-hom-comp {x = G} {z = K} {f} {g} {xᴰ} {zᴰ} fᴰ gᴰ = 𝔹ᴰ₁PathP (𝔹ᴰ₀ zᴰ) refl
𝔹-hom-id : ∀ {x} (xᴰ : GroupActionᴰ.ob[ x ])
→ PathP (λ i → SetBundle.hom[ 𝔹.F-hom-id x i ] (𝔹ᴰ₀ xᴰ) (𝔹ᴰ₀ xᴰ))
(SetBundle.id-homᴰ (𝔹ᴰ₀ xᴰ))
(𝔹ᴰ₁ (GroupActionᴰ.id-homᴰ xᴰ))
𝔹-hom-id {x} xᴰ = 𝔹ᴰ₁PathP (𝔹ᴰ₀ xᴰ) refl
𝔹ᴰ : StrictFunctorᴰ 𝔹 (GroupActionᴰ ℓ) (SetBundleᴰ ℓ)
𝔹ᴰ .StrictFunctorᴰ.F-obᴰ = 𝔹ᴰ₀
𝔹ᴰ .StrictFunctorᴰ.F-homᴰ = 𝔹ᴰ₁
𝔹ᴰ .StrictFunctorᴰ.F-relᴰ = 𝔹ᴰ₂
𝔹ᴰ .StrictFunctorᴰ.F-rel-idᴰ = 𝔹-rel-id
𝔹ᴰ .StrictFunctorᴰ.F-rel-transᴰ = 𝔹-rel-trans
𝔹ᴰ .StrictFunctorᴰ.F-hom-compᴰ = 𝔹-hom-comp
𝔹ᴰ .StrictFunctorᴰ.F-hom-idᴰ = 𝔹-hom-id
𝔹ᴰ .StrictFunctorᴰ.F-assoc-filler-leftᴰ fᴰ gᴰ hᴰ = doubleCompPathP→DoubleCompPathPFiller _ _ _ _
𝔹ᴰ .StrictFunctorᴰ.F-assoc-filler-rightᴰ fᴰ gᴰ hᴰ = doubleCompPathP→DoubleCompPathPFiller _ _ _ _
𝔹ᴰ .StrictFunctorᴰ.F-assocᴰ {f} {g} {h} {xᴰ} {wᴰ} fᴰ gᴰ hᴰ = isSet→SquareP (λ i j → SetBundle.isSetHomᴰ (𝔹.F-assoc f g h i j) (𝔹ᴰ₀ xᴰ) (𝔹ᴰ₀ wᴰ)) _ _ _ _
𝔹ᴰ .StrictFunctorᴰ.F-unit-left-fillerᴰ fᴰ = doubleCompPathP→DoubleCompPathPFiller _ _ _ _
𝔹ᴰ .StrictFunctorᴰ.F-unit-leftᴰ {f} {xᴰ} {yᴰ} fᴰ = isSet→SquareP (λ i j → SetBundle.isSetHomᴰ (𝔹.F-unit-left f i j) (𝔹ᴰ₀ xᴰ) (𝔹ᴰ₀ yᴰ)) _ _ _ _
𝔹ᴰ .StrictFunctorᴰ.F-unit-right-fillerᴰ fᴰ = doubleCompPathP→DoubleCompPathPFiller _ _ _ _
𝔹ᴰ .StrictFunctorᴰ.F-unit-rightᴰ {f} {xᴰ} {yᴰ} fᴰ = isSet→SquareP (λ i j → SetBundle.isSetHomᴰ (𝔹.F-unit-right f i j) (𝔹ᴰ₀ xᴰ) (𝔹ᴰ₀ yᴰ)) _ _ _ _
ActionDelooping : StrictFunctor (GroupAction ℓ) (SetBundle ℓ)
ActionDelooping = StrictFunctorᴰ.toTotalFunctor 𝔹ᴰ
private
module ∫𝔹ᴰ = StrictFunctor ActionDelooping
private
module ActionDelooping where
open StrictFunctor ActionDelooping public
open LocalFunctor ActionDelooping public
isConnectedDeloopingBase : (σ : GroupAction.ob) → isPathConnected ⟨ SetBundle.Base (∫𝔹ᴰ.₀ σ) ⟩
isConnectedDeloopingBase (G , (X , σ)) = Delooping.isConnectedDelooping G
isLocallyFullyFaithfulDelooping : ActionDelooping.isLocallyFullyFaithful
isLocallyFullyFaithfulDelooping σ τ f@(φ , _) g@(ψ , _) = goal where
∫𝔹₁ = StrictFunctor.F-hom ActionDelooping
∫𝔹₂ : GroupAction.rel f g → SetBundle.rel (∫𝔹₁ f) (∫𝔹₁ g)
∫𝔹₂ = StrictFunctor.F-rel ActionDelooping {f = f} {g = g}
∫𝔹₂-equiv : GroupAction.rel f g ≃ SetBundle.rel (∫𝔹₁ f) (∫𝔹₁ g)
∫𝔹₂-equiv = Sigma.Σ-cong-equiv
(TwoFunc.localDeloopingEmbedding ℓ φ ψ)
λ (r : Group.rel φ ψ) → 𝔹ᴰ₂-equiv {r = r}
goal : isEquiv ∫𝔹₂
goal = equivIsEquiv ∫𝔹₂-equiv
module _
{G H : Group.ob}
(Xᴳ @ (X , σ) : GroupActionᴰ.ob[ G ])
(Yᴴ @ (Y , τ) : GroupActionᴰ.ob[ H ])
(f : hGpdCat.hom (𝔹.₀ G) (𝔹.₀ H))
(fᴰ : SetBundle.hom[ f ] (𝔹ᴰ₀ Xᴳ) (𝔹ᴰ₀ Yᴴ))
(φ : Group.hom G H)
(φ-sec : 𝔹.₁ φ ≡ f)
where
𝔹ᴰ₁-sectionOver : Σ[ φᴰ ∈ GroupActionᴰ.hom[ φ ] Xᴳ Yᴴ ] PathP (λ i → SetBundle.hom[ φ-sec i ] (𝔹ᴰ₀ Xᴳ) (𝔹ᴰ₀ Yᴴ)) (𝔹ᴰ₁ φᴰ) fᴰ
𝔹ᴰ₁-sectionOver = goal where
fᴰ′ : SetBundle.hom[ 𝔹.₁ φ ] (𝔹ᴰ₀ Xᴳ) (𝔹ᴰ₀ Yᴴ)
fᴰ′ = subst (λ φ → SetBundle.hom[ φ ] (𝔹ᴰ₀ Xᴳ) (𝔹ᴰ₀ Yᴴ)) (sym φ-sec) fᴰ
fᴰ′-filler : PathP (λ i → SetBundle.hom[ φ-sec (~ i) ] (𝔹ᴰ₀ Xᴳ) (𝔹ᴰ₀ Yᴴ)) fᴰ fᴰ′
fᴰ′-filler = subst-filler (λ φ → SetBundle.hom[ φ ] (𝔹ᴰ₀ Xᴳ) (𝔹ᴰ₀ Yᴴ)) (sym φ-sec) fᴰ
φᴰ : GroupActionᴰ.hom[ φ ] Xᴳ Yᴴ
φᴰ = 𝔹ᴰ₁⁻¹ fᴰ′
φᴰ-sec : fᴰ′ ≡ 𝔹ᴰ₁ φᴰ
φᴰ-sec = sym (Equiv.secEq (𝔹ᴰ₁-equiv {Xᴳ = Xᴳ} {Yᴴ = Yᴴ}) fᴰ′)
goal : Σ _ _
goal .fst = φᴰ
goal .snd = symP (subst (PathP _ fᴰ) φᴰ-sec fᴰ′-filler)
isEssentiallySurjectiveDelooping : ActionDelooping.isLocallyEssentiallySurjective
isEssentiallySurjectiveDelooping Xᴳ@(G , (X , σ)) Yᴴ@(H , (Y , τ)) = goal
where module _ (f* @ (f , fᴰ) : SetBundle.hom (ActionDelooping.₀ Xᴳ) (ActionDelooping.₀ Yᴴ)) where
open import Cubical.HITs.PropositionalTruncation.Monad
open import Cubical.Categories.Category.Base using (CatIso ; pathToIso)
goal : ∃[ φ* ∈ GroupAction.hom Xᴳ Yᴴ ] CatIso (LocalCategory _ (∫𝔹ᴰ.₀ Xᴳ) (∫𝔹ᴰ.₀ Yᴴ)) (∫𝔹ᴰ.₁ φ*) f*
goal = do
(φ , φ-sec) ← LocalInverse.isSurjection-map f
let (φᴰ , φᴰ-sec) = 𝔹ᴰ₁-sectionOver (X , σ) (Y , τ) f fᴰ φ φ-sec
∃-intro (φ , φᴰ) $ pathToIso $ Sigma.ΣPathP (φ-sec , φᴰ-sec)
isLocallyWeakEquivalenceDelooping : ActionDelooping.isLocallyWeakEquivalence
isLocallyWeakEquivalenceDelooping =
ActionDelooping.isLocallyFullyFaithful×EssentiallySurjective→isLocallyWeakEquivalence
isLocallyFullyFaithfulDelooping
isEssentiallySurjectiveDelooping