{-# OPTIONS --safe --lossy-unification #-}
module Cubical.Homotopy.Group.Join where
open import Cubical.Homotopy.Loopspace
open import Cubical.Homotopy.Group.Base
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.Pointed
open import Cubical.Foundations.GroupoidLaws
open import Cubical.Foundations.Isomorphism
open import Cubical.Foundations.Function
open import Cubical.Data.Sigma
open import Cubical.Data.Nat
open import Cubical.Data.Bool
open import Cubical.HITs.SetTruncation as ST
open import Cubical.HITs.Sn
open import Cubical.HITs.Susp renaming (toSusp to σ)
open import Cubical.HITs.S1
open import Cubical.HITs.Join
open import Cubical.HITs.Sn.Multiplication
open import Cubical.Algebra.Group
open import Cubical.Algebra.Group.Morphisms
open import Cubical.Algebra.Group.MorphismProperties
open import Cubical.Algebra.Group.GroupPath
open Iso
open GroupStr
ℓ* : ∀ {ℓ ℓ'} (A : Pointed ℓ) (B : Pointed ℓ')
→ fst A → fst B → Ω (join∙ A B) .fst
ℓ* A B a b = push (pt A) (pt B)
∙ (push a (pt B) ⁻¹ ∙∙ push a b ∙∙ (push (pt A) b ⁻¹))
ℓS : {n m : ℕ} → S₊ n → S₊ m → Ω (join∙ (S₊∙ n) (S₊∙ m)) .fst
ℓS {n = n} {m} = ℓ* (S₊∙ n) (S₊∙ m)
_+*_ : ∀ {ℓ ℓ' ℓ''} {A : Pointed ℓ} {B : Pointed ℓ'} {C : Pointed ℓ''}
(f g : join∙ A B →∙ C) → join∙ A B →∙ C
fst (_+*_ {C = C} f g) (inl x) = pt C
fst (_+*_ {C = C} f g) (inr x) = pt C
fst (_+*_ {A = A} {B = B} f g) (push a b i) =
(Ω→ f .fst (ℓ* A B a b) ∙ Ω→ g .fst (ℓ* A B a b)) i
snd (f +* g) = refl
-* : ∀ {ℓ ℓ' ℓ''} {A : Pointed ℓ} {B : Pointed ℓ'} {C : Pointed ℓ''}
(f : join∙ A B →∙ C) → join∙ A B →∙ C
fst (-* {C = C} f) (inl x) = pt C
fst (-* {C = C} f) (inr x) = pt C
fst (-* {A = A} {B} f) (push a b i) = Ω→ f .fst (ℓ* A B a b) (~ i)
snd (-* f) = refl
-Π≡-* : ∀ {ℓ} {A : Pointed ℓ} {n m : ℕ}
(f : S₊∙ (suc (n + m)) →∙ A)
→ (-Π f) ∘∙ join→Sphere∙ n m
≡ -* (f ∘∙ join→Sphere∙ n m)
fst (-Π≡-* f i) (inl x) = snd (-Π f) i
fst (-Π≡-* f i) (inr x) = snd (-Π f) i
fst (-Π≡-* {A = A} {n = n} {m = m} f i) (push a b j) = main i j
where
lem : (n : ℕ) (f : S₊∙ (suc n) →∙ A) (a : S₊ n)
→ Square (cong (fst (-Π f)) (σS a))
(sym (snd f) ∙∙ cong (fst f) (sym (σS a)) ∙∙ snd f)
(snd (-Π f)) (snd (-Π f))
lem zero f false =
doubleCompPath-filler (sym (snd f)) (cong (fst f) (sym loop)) (snd f)
lem zero f true = doubleCompPath-filler (sym (snd f)) refl (snd f)
lem (suc n) f a =
(cong-∙ (fst (-Π f)) (merid a) (sym (merid (ptSn (suc n))))
∙ cong₂ _∙_ refl (cong (cong (fst f)) (rCancel _))
∙ sym (rUnit _))
◁ doubleCompPath-filler
(sym (snd f)) (cong (fst f) (sym (σS a))) (snd f)
main : Square (cong (fst (-Π f)) (σS (a ⌣S b)))
(sym (Ω→ (f ∘∙ join→Sphere∙ n m) .fst (ℓS a b)))
(snd (-Π f)) (snd (-Π f))
main = lem _ f (a ⌣S b)
▷ sym ((λ j → (sym (lUnit (snd f) (~ j))
∙∙ sym (cong (fst f) (cong-∙ (join→Sphere n m)
(push (ptSn n) (ptSn m))
((push a (ptSn m) ⁻¹)
∙∙ push a b
∙∙ (push (ptSn n) b ⁻¹)) j))
∙∙ lUnit (snd f) (~ j)))
∙ cong (sym (snd f) ∙∙_∙∙ snd f)
(cong (cong (fst f))
(congS sym
((cong₂ _∙_
(cong σS (IdL⌣S _) ∙ σS∙)
(cong-∙∙ (join→Sphere n m)
(push a (ptSn m) ⁻¹) (push a b) (push (ptSn n) b ⁻¹)
∙ (cong₂ (λ p q → p ⁻¹ ∙∙ σS (a ⌣S b) ∙∙ q ⁻¹)
(cong σS (IdL⌣S _) ∙ σS∙)
(cong σS (IdR⌣S _) ∙ σS∙))
∙ sym (rUnit (σS (a ⌣S b)))))
∙ sym (lUnit _)))))
snd (-Π≡-* f i) j = lem i j
where
lem : Square (refl ∙ snd (-Π f)) refl (snd (-Π f)) refl
lem = sym (lUnit (snd (-Π f))) ◁ λ i j → (snd (-Π f)) (i ∨ j)
·Π≡+* : ∀ {ℓ} {A : Pointed ℓ} {n m : ℕ}
(f g : S₊∙ (suc (n + m)) →∙ A)
→ (∙Π f g ∘∙ join→Sphere∙ n m)
≡ ((f ∘∙ join→Sphere∙ n m)
+* (g ∘∙ join→Sphere∙ n m))
fst (·Π≡+* {A = A} f g i) (inl x) = snd (∙Π f g) i
fst (·Π≡+* {A = A} f g i) (inr x) = snd (∙Π f g) i
fst (·Π≡+* {A = A} {n = n} {m} f g i) (push a b j) = main i j
where
help : (n : ℕ) (f g : S₊∙ (suc n) →∙ A) (a : S₊ n)
→ Square (cong (fst (∙Π f g)) (σS a))
(Ω→ f .fst (σS a) ∙ Ω→ g .fst (σS a))
(snd (∙Π f g)) (snd (∙Π f g))
help zero f g false = refl
help zero f g true =
rUnit refl
∙ cong₂ _∙_ (sym (∙∙lCancel (snd f))) (sym (∙∙lCancel (snd g)))
help (suc n) f g a =
cong-∙ (fst (∙Π f g)) (merid a) (sym (merid (ptSn (suc n))))
∙ cong (cong (fst (∙Π f g)) (merid a) ∙_)
(congS sym
(cong₂ _∙_
(cong (sym (snd f) ∙∙_∙∙ snd f)
(cong (cong (fst f)) (rCancel (merid (ptSn (suc n)))))
∙ Ω→ f .snd)
(cong (sym (snd g) ∙∙_∙∙ snd g)
(cong (cong (fst g)) (rCancel (merid (ptSn (suc n)))))
∙ Ω→ g .snd)
∙ sym (rUnit refl)))
∙ sym (rUnit _)
Ω→σ : ∀ {ℓ} {A : Pointed ℓ} (f : S₊∙ (suc (n + m)) →∙ A)
→ Ω→ f .fst (σS (a ⌣S b))
≡ Ω→ (f ∘∙ join→Sphere∙ n m) .fst (ℓS a b)
Ω→σ f =
cong (sym (snd f) ∙∙_∙∙ snd f)
(cong (cong (fst f))
(sym main))
∙ λ i → Ω→ (lem (~ i)) .fst (ℓS a b)
where
main : cong (join→Sphere n m) (ℓS a b) ≡ σS (a ⌣S b)
main = cong-∙ (join→Sphere n m) _ _
∙ cong₂ _∙_
(cong σS (IdL⌣S _) ∙ σS∙)
(cong-∙∙ (join→Sphere n m) _ _ _
∙ (λ i → sym ((cong σS (IdL⌣S a) ∙ σS∙) i)
∙∙ σS (a ⌣S b)
∙∙ sym ((cong σS (IdR⌣S b) ∙ σS∙) i))
∙ sym (rUnit (σS (a ⌣S b))) )
∙ sym (lUnit (σS (a ⌣S b)))
lem : f ∘∙ join→Sphere∙ n m ≡ (fst f ∘ join→Sphere n m , snd f)
lem = ΣPathP (refl , (sym (lUnit _)))
main : Square (cong (fst (∙Π f g)) (σS (a ⌣S b)))
(Ω→ (f ∘∙ join→Sphere∙ n m) .fst (ℓS a b)
∙ Ω→ (g ∘∙ join→Sphere∙ n m) .fst (ℓS a b))
(snd (∙Π f g)) (snd (∙Π f g))
main = help _ f g (a ⌣S b) ▷ cong₂ _∙_ (Ω→σ f) (Ω→σ g)
snd (·Π≡+* {A = A} f g i) j = lem i j
where
lem : Square (refl ∙ snd (∙Π f g)) refl (snd (∙Π f g)) refl
lem = sym (lUnit (snd (∙Π f g))) ◁ λ i j → (snd (∙Π f g)) (i ∨ j)
π* : ∀ {ℓ} (n m : ℕ) (A : Pointed ℓ) → Type ℓ
π* n m A = ∥ join∙ (S₊∙ n) (S₊∙ m) →∙ A ∥₂
·π* : ∀ {ℓ} {n m : ℕ} {A : Pointed ℓ} (f g : π* n m A) → π* n m A
·π* = ST.rec2 squash₂ λ f g → ∣ f +* g ∣₂
-π* : ∀ {ℓ} {n m : ℕ} {A : Pointed ℓ} (f : π* n m A) → π* n m A
-π* = ST.map -*
1π* : ∀ {ℓ} {n m : ℕ} {A : Pointed ℓ} → π* n m A
1π* = ∣ const∙ _ _ ∣₂
Iso-JoinMap-SphereMap : ∀ {ℓ} {A : Pointed ℓ} (n m : ℕ)
→ Iso (join∙ (S₊∙ n) (S₊∙ m) →∙ A)
(S₊∙ (suc (n + m)) →∙ A)
Iso-JoinMap-SphereMap n m = post∘∙equiv (joinSphereEquiv∙ n m)
Iso-π*-π' : ∀ {ℓ} {A : Pointed ℓ} (n m : ℕ)
→ Iso ∥ (join∙ (S₊∙ n) (S₊∙ m) →∙ A) ∥₂
∥ (S₊∙ (suc (n + m)) →∙ A) ∥₂
Iso-π*-π' n m = setTruncIso (Iso-JoinMap-SphereMap n m)
private
J≃∙map : ∀ {ℓ ℓ' ℓ''} {A1 A2 : Pointed ℓ} {A : Pointed ℓ'}
→ (e : A1 ≃∙ A2) {P : A1 →∙ A → Type ℓ''}
→ ((f : A2 →∙ A) → P (f ∘∙ ≃∙map e))
→ (f : _) → P f
J≃∙map {ℓ'' = ℓ''} {A2 = A2} {A = A} =
Equiv∙J (λ A1 e → {P : A1 →∙ A → Type ℓ''}
→ ((f : A2 →∙ A) → P (f ∘∙ ≃∙map e))
→ (f : _) → P f)
λ {P} ind f
→ subst P (ΣPathP (refl , sym (lUnit (snd f)))) (ind f)
π*≡π' : ∀ {ℓ} {A : Pointed ℓ} {n m : ℕ}
(f g : π* n m A)
→ Iso.fun (Iso-π*-π' n m) (·π* f g)
≡ ·π' _ (Iso.fun (Iso-π*-π' n m) f) (Iso.fun (Iso-π*-π' n m) g)
π*≡π' {A = A} {n} {m} = ST.elim2 (λ _ _ → isSetPathImplicit)
(J≃∙map (joinSphereEquiv∙ n m)
λ f → J≃∙map (joinSphereEquiv∙ n m)
λ g → cong ∣_∣₂
(cong (fun (Iso-JoinMap-SphereMap n m)) (sym (·Π≡+* f g))
∙ ∘∙-assoc _ _ _
∙ cong (∙Π f g ∘∙_) ret
∙ ∘∙-idˡ (∙Π f g)
∙ cong₂ ∙Π
((sym (∘∙-idˡ f) ∙ cong (f ∘∙_) (sym ret)) ∙ sym (∘∙-assoc _ _ _))
(sym (∘∙-idˡ g) ∙ cong (g ∘∙_) (sym ret) ∙ sym (∘∙-assoc _ _ _))))
where
ret = ≃∙→ret/sec∙ {B = _ , ptSn (suc (n + m))}
(joinSphereEquiv∙ n m) .snd
-π*≡-π' : ∀ {ℓ} {A : Pointed ℓ} {n m : ℕ}
(f : π* n m A)
→ Iso.fun (Iso-π*-π' n m) (-π* f)
≡ -π' _ (Iso.fun (Iso-π*-π' n m) f)
-π*≡-π' {n = n} {m} =
ST.elim (λ _ → isSetPathImplicit)
(J≃∙map (joinSphereEquiv∙ n m)
λ f → cong ∣_∣₂
(cong (_∘∙ (≃∙map (invEquiv∙ (joinSphereEquiv∙ n m))))
(sym (-Π≡-* f))
∙ ∘∙-assoc _ _ _
∙ cong (-Π f ∘∙_) ret
∙ ∘∙-idˡ (-Π f)
∙ cong -Π (sym (∘∙-assoc _ _ _ ∙ cong (f ∘∙_) ret ∙ ∘∙-idˡ f))))
where
ret = ≃∙→ret/sec∙ {B = _ , ptSn (suc (n + m))}
(joinSphereEquiv∙ n m) .snd
π*Gr : ∀ {ℓ} (n m : ℕ) (A : Pointed ℓ) → Group ℓ
fst (π*Gr n m A) = π* n m A
1g (snd (π*Gr n m A)) = 1π*
GroupStr._·_ (snd (π*Gr n m A)) = ·π*
inv (snd (π*Gr n m A)) = -π*
isGroup (snd (π*Gr n m A)) =
transport (λ i → IsGroup (p1 (~ i)) (p2 (~ i)) (p3 (~ i)))
(isGroup (π'Gr (n + m) A .snd))
where
p1 : PathP (λ i → isoToPath (Iso-π*-π' {A = A} n m) i)
1π* (1π' (suc (n + m)))
p1 = toPathP (cong ∣_∣₂ (transportRefl _ ∙ ΣPathP (refl , sym (rUnit refl))))
p2 : PathP (λ i → (f g : isoToPath (Iso-π*-π' {A = A} n m) i)
→ isoToPath (Iso-π*-π' {A = A} n m) i)
·π* (·π' _)
p2 = toPathP (funExt λ f
→ funExt λ g → transportRefl _
∙ π*≡π' _ _
∙ cong₂ (·π' (n + m))
(Iso.rightInv (Iso-π*-π' n m) _ ∙ transportRefl f)
(Iso.rightInv (Iso-π*-π' n m) _ ∙ transportRefl g))
p3 : PathP (λ i → isoToPath (Iso-π*-π' {A = A} n m) i
→ isoToPath (Iso-π*-π' {A = A} n m) i)
-π* (-π' _)
p3 = toPathP (funExt λ f → transportRefl _
∙ -π*≡-π' _
∙ cong (-π' (n + m))
(Iso.rightInv (Iso-π*-π' n m) _ ∙ transportRefl f))
π*Gr≅π'Gr : ∀ {ℓ} (n m : ℕ) (A : Pointed ℓ)
→ GroupIso (π*Gr n m A) (π'Gr (n + m) A)
fst (π*Gr≅π'Gr n m A) = Iso-π*-π' {A = A} n m
snd (π*Gr≅π'Gr n m A) = makeIsGroupHom π*≡π'
π*∘∙fun : ∀ {ℓ ℓ'} {A : Pointed ℓ} {B : Pointed ℓ'}
(n m : ℕ) (f : A →∙ B)
→ π* n m A → π* n m B
π*∘∙fun n m f = ST.map (f ∘∙_)
π*∘∙Hom : ∀ {ℓ ℓ'} {A : Pointed ℓ} {B : Pointed ℓ'}
(n m : ℕ) (f : A →∙ B)
→ GroupHom (π*Gr n m A) (π*Gr n m B)
fst (π*∘∙Hom {A = A} {B = B} n m f) = π*∘∙fun n m f
snd (π*∘∙Hom {A = A} {B = B} n m f) =
subst (λ ϕ → IsGroupHom (π*Gr n m A .snd) ϕ (π*Gr n m B .snd))
π*∘∙Hom'≡
(snd π*∘∙Hom')
where
GroupHomπ≅π*PathP : ∀ {ℓ ℓ'} (A : Pointed ℓ) (B : Pointed ℓ') (n m : ℕ)
→ GroupHom (π'Gr (n + m) A) (π'Gr (n + m) B)
≡ GroupHom (π*Gr n m A) (π*Gr n m B)
GroupHomπ≅π*PathP A B n m i =
GroupHom (fst (GroupPath _ _) (GroupIso→GroupEquiv (π*Gr≅π'Gr n m A)) (~ i))
(fst (GroupPath _ _) (GroupIso→GroupEquiv (π*Gr≅π'Gr n m B)) (~ i))
π*∘∙Hom' : _
π*∘∙Hom' = transport (λ i → GroupHomπ≅π*PathP A B n m i)
(π'∘∙Hom (n + m) f)
π*∘∙Hom'≡ : π*∘∙Hom' .fst ≡ π*∘∙fun n m f
π*∘∙Hom'≡ =
funExt (ST.elim (λ _ → isSetPathImplicit)
λ g → cong ∣_∣₂ (cong (inv (Iso-JoinMap-SphereMap n m))
(transportRefl _
∙ cong (f ∘∙_) (transportRefl _))
∙ ∘∙-assoc _ _ _
∙ cong (f ∘∙_ )
(∘∙-assoc _ _ _ ∙ cong (g ∘∙_)
(≃∙→ret/sec∙ {B = _ , ptSn (suc (n + m))}
(joinSphereEquiv∙ n m) .fst)
∙ ∘∙-idˡ g)))
π*∘∙Equiv : ∀ {ℓ ℓ'} {A : Pointed ℓ} {B : Pointed ℓ'}
(n m : ℕ) (f : A ≃∙ B)
→ GroupEquiv (π*Gr n m A) (π*Gr n m B)
fst (π*∘∙Equiv n m f) = isoToEquiv (setTruncIso (pre∘∙equiv f))
snd (π*∘∙Equiv n m f) = π*∘∙Hom n m (≃∙map f) .snd