{-# OPTIONS --erased-cubical --safe #-}
import Equality.Path as P
module Eilenberg-MacLane-space
{e⁺} (eq : ∀ {a p} → P.Equality-with-paths a p e⁺) where
open P.Derived-definitions-and-properties eq hiding (elim)
open import Logical-equivalence using (_⇔_)
open import Prelude as P hiding (id) renaming (_∘_ to _⊚_)
open import Bijection equality-with-J as B using (_↔_)
open import Embedding equality-with-J using (Embedding; Is-embedding)
import Equality.Groupoid equality-with-J as EG
open import Equality.Path.Isomorphisms eq
open import Equivalence equality-with-J as Eq
using (_≃_; Is-equivalence)
import Equivalence P.equality-with-J as PEq
open import Extensionality equality-with-J
open import Function-universe equality-with-J hiding (id; _∘_)
open import Group equality-with-J
open import H-level equality-with-J as H-level
import H-level P.equality-with-J as PH
open import H-level.Closure equality-with-J
open import H-level.Truncation eq as T using (∥_∥[1+_]; ∣_∣)
open import H-level.Truncation.Propositional eq as TP using (Surjective)
open import Pointed-type equality-with-J
open import Pointed-type.Connected eq
open import Pointed-type.Homotopy-group eq
open import Univalence-axiom equality-with-J
private
variable
a p : Level
A : Type a
P : A → Type p
e g x y : A
G G₁ G₂ : Group g
data K[_]1 (G : Group g) : Type g where
base : K[ G ]1
loopᴾ : Group.Carrier G → base P.≡ base
loop-idᴾ : loopᴾ (Group.id G) P.≡ P.refl
loop-∘ᴾ : loopᴾ (Group._∘_ G x y) P.≡ P.htransˡ (loopᴾ x) (loopᴾ y)
is-groupoidᴾ : PH.H-level 3 K[ G ]1
loop : Group.Carrier G → base ≡ base
loop {G} = _↔_.from ≡↔≡ ⊚ loopᴾ {G = G}
loop-id : loop {G = G} (Group.id G) ≡ refl base
loop-id {G} =
loop id ≡⟨ _≃_.from (Eq.≃-≡ (Eq.↔⇒≃ (inverse ≡↔≡))) (_↔_.from ≡↔≡ loop-idᴾ) ⟩
_↔_.from ≡↔≡ P.refl ≡⟨ from-≡↔≡-refl ⟩∎
refl base ∎
where
open Group G
loop-∘ : loop {G = G} (Group._∘_ G x y) ≡ trans (loop x) (loop y)
loop-∘ {G} {x} {y} =
loop (Group._∘_ G x y) ≡⟨ _≃_.from (Eq.≃-≡ (Eq.↔⇒≃ (inverse ≡↔≡))) (_↔_.from ≡↔≡ loop-∘ᴾ) ⟩
_↔_.from ≡↔≡ (P.trans (loopᴾ x) (loopᴾ y)) ≡⟨ sym trans≡trans ⟩∎
trans (loop x) (loop y) ∎
is-groupoid : H-level 3 K[ G ]1
is-groupoid = _↔_.from (H-level↔H-level 3) is-groupoidᴾ
record Elimᴾ {G : Group g} (P : K[ G ]1 → Type p) : Type (g ⊔ p) where
no-eta-equality
open Group G
field
baseʳ : P base
loopʳ : ∀ g → P.[ (λ i → P (loopᴾ g i)) ] baseʳ ≡ baseʳ
loop-idʳ : P.[ (λ i → P.[ (λ j → P (loop-idᴾ i j)) ]
baseʳ ≡ baseʳ) ]
loopʳ id ≡ P.refl {x = baseʳ}
loop-∘ʳ : P.[ (λ i →
P.[ (λ j → P (loop-∘ᴾ {x = x} {y = y} i j)) ]
baseʳ ≡ baseʳ) ]
loopʳ (x ∘ y) ≡ P.htrans P (loopʳ x) (loopʳ y)
is-groupoidʳ : ∀ x → PH.H-level 3 (P x)
open Elimᴾ public
elimᴾ : Elimᴾ P → (x : K[ G ]1) → P x
elimᴾ {G} {P} e = helper
where
module E = Elimᴾ e
helper : (x : K[ G ]1) → P x
helper base = E.baseʳ
helper (loopᴾ x i) = E.loopʳ x i
helper (loop-idᴾ i j) = E.loop-idʳ i j
helper (loop-∘ᴾ i j) = E.loop-∘ʳ i j
helper (is-groupoidᴾ p q i j k) =
P.heterogeneous-UIP₃ E.is-groupoidʳ (is-groupoidᴾ p q)
(λ j k → helper (p j k)) (λ j k → helper (q j k)) i j k
record Recᴾ (G : Group g) (A : Type a) : Type (g ⊔ a) where
no-eta-equality
open Group G
field
baseʳ : A
loopʳ : Carrier → baseʳ P.≡ baseʳ
loop-idʳ : loopʳ id P.≡ P.refl
loop-∘ʳ : loopʳ (x ∘ y) P.≡ P.trans (loopʳ x) (loopʳ y)
is-groupoidʳ : PH.H-level 3 A
open Recᴾ public
recᴾ : Recᴾ G A → K[ G ]1 → A
recᴾ {G} {A} r = elimᴾ λ where
.is-groupoidʳ _ → R.is-groupoidʳ
.baseʳ → R.baseʳ
.loopʳ → R.loopʳ
.loop-idʳ → R.loop-idʳ
.loop-∘ʳ {x} {y} →
R.loopʳ (x ∘ y) P.≡⟨ R.loop-∘ʳ ⟩
P.trans (R.loopʳ x) (R.loopʳ y) P.≡⟨ P.sym $ P.htrans-const (loopᴾ {G = G} x) (loopᴾ y) (R.loopʳ x) ⟩∎
P.htrans {x≡y = loopᴾ {G = G} x} {y≡z = loopᴾ y} (const A)
(R.loopʳ x) (R.loopʳ y) ∎
where
open Group G
module R = Recᴾ r
record Rec (G : Group g) (A : Type a) : Type (g ⊔ a) where
no-eta-equality
open Group G
field
baseʳ : A
loopʳ : Carrier → baseʳ ≡ baseʳ
loop-idʳ : loopʳ id ≡ refl baseʳ
loop-∘ʳ : loopʳ (x ∘ y) ≡ trans (loopʳ x) (loopʳ y)
is-groupoidʳ : H-level 3 A
open Rec public
rec : Rec G A → K[ G ]1 → A
rec {G} {A} r = recᴾ λ where
.is-groupoidʳ → _↔_.to (H-level↔H-level 3) R.is-groupoidʳ
.baseʳ → R.baseʳ
.loopʳ → _↔_.to ≡↔≡ ⊚ R.loopʳ
.loop-idʳ →
_↔_.to ≡↔≡ (R.loopʳ id) P.≡⟨ P.cong (_↔_.to ≡↔≡) $ _↔_.to ≡↔≡ R.loop-idʳ ⟩
_↔_.to ≡↔≡ (refl R.baseʳ) P.≡⟨ _↔_.to ≡↔≡ to-≡↔≡-refl ⟩∎
P.refl ∎
.loop-∘ʳ {x} {y} →
_↔_.to ≡↔≡ (R.loopʳ (x ∘ y)) P.≡⟨ P.cong (_↔_.to ≡↔≡) $ _↔_.to ≡↔≡ R.loop-∘ʳ ⟩
_↔_.to ≡↔≡ (trans (R.loopʳ x) (R.loopʳ y)) P.≡⟨ _↔_.to ≡↔≡ $ sym $ cong₂ (λ p q → _↔_.to ≡↔≡ (trans p q))
(_↔_.left-inverse-of ≡↔≡ _)
(_↔_.left-inverse-of ≡↔≡ _) ⟩
_↔_.to ≡↔≡ (trans (_↔_.from ≡↔≡ (_↔_.to ≡↔≡ (R.loopʳ x)))
(_↔_.from ≡↔≡ (_↔_.to ≡↔≡ (R.loopʳ y)))) P.≡⟨ P.cong (_↔_.to ≡↔≡) $ _↔_.to ≡↔≡ trans≡trans ⟩
(_↔_.to ≡↔≡ $ _↔_.from ≡↔≡ $
P.trans (_↔_.to ≡↔≡ (R.loopʳ x)) (_↔_.to ≡↔≡ (R.loopʳ y))) P.≡⟨ _↔_.to ≡↔≡ $ _↔_.right-inverse-of ≡↔≡ _ ⟩∎
P.trans (_↔_.to ≡↔≡ (R.loopʳ x)) (_↔_.to ≡↔≡ (R.loopʳ y)) ∎
where
open Group G
module R = Rec r
rec-loop : cong (rec e) (loop g) ≡ e .loopʳ g
rec-loop = cong-≡↔≡ (refl _)
record Elim-setᴾ {G : Group g}
(P : K[ G ]1 → Type p) : Type (g ⊔ p) where
no-eta-equality
open Group G
field
baseʳ : P base
loopʳ : ∀ g → P.[ (λ i → P (loopᴾ g i)) ] baseʳ ≡ baseʳ
is-setʳ : ∀ x → P.Is-set (P x)
open Elim-setᴾ public
elim-setᴾ : Elim-setᴾ P → (x : K[ G ]1) → P x
elim-setᴾ e = elimᴾ λ where
.baseʳ → E.baseʳ
.loopʳ → E.loopʳ
.loop-idʳ → P.heterogeneous-UIP E.is-setʳ _ _ _
.loop-∘ʳ → P.heterogeneous-UIP E.is-setʳ _ _ _
.is-groupoidʳ → PH.mono₁ 2 ⊚ E.is-setʳ
where
module E = Elim-setᴾ e
record Elim-set {G : Group g}
(P : K[ G ]1 → Type p) : Type (g ⊔ p) where
no-eta-equality
open Group G
field
baseʳ : P base
loopʳ : ∀ g → subst P (loop g) baseʳ ≡ baseʳ
is-setʳ : ∀ x → Is-set (P x)
open Elim-set public
elim-set : Elim-set P → (x : K[ G ]1) → P x
elim-set e = elim-setᴾ λ where
.baseʳ → E.baseʳ
.loopʳ → subst≡→[]≡ ⊚ E.loopʳ
.is-setʳ → _↔_.to (H-level↔H-level 2) ⊚ E.is-setʳ
where
module E = Elim-set e
elim-set-loop : dcong (elim-set e) (loop g) ≡ e .loopʳ g
elim-set-loop = dcong-subst≡→[]≡ (refl _)
record Rec-setᴾ (G : Group g) (A : Type a) : Type (g ⊔ a) where
no-eta-equality
open Group G
field
baseʳ : A
loopʳ : Carrier → baseʳ P.≡ baseʳ
is-setʳ : P.Is-set A
open Rec-setᴾ public
rec-setᴾ : Rec-setᴾ G A → K[ G ]1 → A
rec-setᴾ r = elim-setᴾ λ where
.baseʳ → R.baseʳ
.loopʳ → R.loopʳ
.is-setʳ _ → R.is-setʳ
where
module R = Rec-setᴾ r
record Rec-set (G : Group g) (A : Type a) : Type (g ⊔ a) where
no-eta-equality
open Group G
field
baseʳ : A
loopʳ : Carrier → baseʳ ≡ baseʳ
is-setʳ : Is-set A
open Rec-set public
rec-set : Rec-set G A → K[ G ]1 → A
rec-set r = rec-setᴾ λ where
.baseʳ → R.baseʳ
.loopʳ → _↔_.to ≡↔≡ ⊚ R.loopʳ
.is-setʳ → _↔_.to (H-level↔H-level 2) R.is-setʳ
where
module R = Rec-set r
rec-set-loop : cong (rec-set e) (loop g) ≡ e .loopʳ g
rec-set-loop = cong-≡↔≡ (refl _)
record Elim-prop {G : Group g} (P : K[ G ]1 → Type p) :
Type (g ⊔ p) where
no-eta-equality
field
baseʳ : P base
is-propositionʳ : ∀ x → Is-proposition (P x)
open Elim-prop public
elim-prop : Elim-prop P → (x : K[ G ]1) → P x
elim-prop e = elim-set λ where
.baseʳ → E.baseʳ
.loopʳ _ → E.is-propositionʳ _ _ _
.is-setʳ → mono₁ 1 ⊚ E.is-propositionʳ
where
module E = Elim-prop e
universal-property-Π-setᴾ :
(∀ x → P.Is-set (P x)) →
((x : K[ G ]1) → P x) ≃
(∃ λ (x : P base) → ∀ g → P.[ (λ i → P (loopᴾ g i)) ] x ≡ x)
universal-property-Π-setᴾ {G} {P} P-set =
_↔_.from ≃↔≃ $
PEq.↔→≃
(λ f → f base , P.hcong f ⊚ loopᴾ)
(λ (x , f) → elim-setᴾ λ where
.baseʳ → x
.loopʳ → f
.is-setʳ → P-set)
(λ _ → P.refl)
(λ f → P.⟨ext⟩ $ elim-setᴾ λ where
.baseʳ → P.refl
.loopʳ _ _ → P.refl
.is-setʳ _ → PH.mono₁ 2 (P-set _))
universal-property-Π-set :
(∀ x → Is-set (P x)) →
((x : K[ G ]1) → P x) ≃
(∃ λ (x : P base) → ∀ g → subst P (loop g) x ≡ x)
universal-property-Π-set {G} {P} P-set =
((x : K[ G ]1) → P x) ↝⟨ universal-property-Π-setᴾ (_↔_.to (H-level↔H-level 2) ⊚ P-set) ⟩
(∃ λ (x : P base) → ∀ g → P.[ (λ i → P (loopᴾ g i)) ] x ≡ x) ↔⟨ (∃-cong λ _ → ∀-cong ext λ _ → inverse subst≡↔[]≡) ⟩□
(∃ λ (x : P base) → ∀ g → subst P (loop g) x ≡ x) □
universal-property-set :
Is-set A →
(K[ G ]1 → A) ≃ (∃ λ (x : A) → Group.Carrier G → x ≡ x)
universal-property-set {A} {G} A-set =
(K[ G ]1 → A) ↝⟨ universal-property-Π-setᴾ (λ _ → _↔_.to (H-level↔H-level 2) A-set) ⟩
(∃ λ (x : A) → Carrier → x P.≡ x) ↔⟨ (∃-cong λ _ → ∀-cong ext λ _ → inverse ≡↔≡) ⟩□
(∃ λ (x : A) → Carrier → x ≡ x) □
where
open Group G
map : G₁ →ᴳ G₂ → K[ G₁ ]1 → K[ G₂ ]1
map {G₁} {G₂} h = rec λ where
.is-groupoidʳ → is-groupoid
.baseʳ → base
.loopʳ x → loop (to x)
.loop-idʳ →
loop (to G₁.id) ≡⟨ cong loop (→ᴳ-id h) ⟩
loop G₂.id ≡⟨ loop-id ⟩∎
refl _ ∎
.loop-∘ʳ {x} {y} →
loop (to (x G₁.∘ y)) ≡⟨ cong loop (h .homomorphic x y) ⟩
loop (to x G₂.∘ to y) ≡⟨ loop-∘ ⟩∎
trans (loop (to x)) (loop (to y)) ∎
where
module G₁ = Group G₁
module G₂ = Group G₂
open Homomorphic h using (to)
cong-≃ : G₁ ≃ᴳ G₂ → K[ G₁ ]1 ≃ K[ G₂ ]1
cong-≃ G₁≃G₂ = Eq.↔→≃
(map (↝ᴳ→→ᴳ G₁≃G₂))
(map (↝ᴳ→→ᴳ (≃ᴳ-sym G₁≃G₂)))
(lemma (↝ᴳ→→ᴳ G₁≃G₂) (↝ᴳ→→ᴳ (≃ᴳ-sym G₁≃G₂))
(_≃_.right-inverse-of (related G₁≃G₂)))
(lemma (↝ᴳ→→ᴳ (≃ᴳ-sym G₁≃G₂)) (↝ᴳ→→ᴳ G₁≃G₂)
(_≃_.left-inverse-of (related G₁≃G₂)))
where
open Homomorphic using (to)
lemma :
(f₁ : G₁ →ᴳ G₂) (f₂ : G₂ →ᴳ G₁) →
(∀ x → to f₁ (to f₂ x) ≡ x) →
∀ x → map f₁ (map f₂ x) ≡ x
lemma f₁ f₂ hyp = elim-set λ where
.is-setʳ _ → is-groupoid
.baseʳ → refl _
.loopʳ g →
subst (λ x → map f₁ (map f₂ x) ≡ x) (loop g) (refl _) ≡⟨ subst-in-terms-of-trans-and-cong ⟩
trans (sym $ cong (map f₁ ⊚ map f₂) (loop g))
(trans (refl _) (cong P.id (loop g))) ≡⟨ cong₂ (trans ⊚ sym)
(sym $ cong-∘ _ _ _)
(trans (trans-reflˡ _) $
sym $ cong-id _) ⟩
trans (sym $ cong (map f₁) $ cong (map f₂) (loop g)) (loop g) ≡⟨ cong (flip trans (loop g) ⊚ sym) $
trans (cong (cong _) rec-loop)
rec-loop ⟩
trans (sym $ loop (to f₁ (to f₂ g))) (loop g) ≡⟨ cong (flip trans _ ⊚ sym ⊚ loop) $ hyp _ ⟩
trans (sym $ loop g) (loop g) ≡⟨ trans-symˡ _ ⟩∎
refl _ ∎
connected : Connected (K[ G ]1 , base)
connected = elim-prop λ where
.is-propositionʳ _ → TP.truncation-is-proposition
.baseʳ → TP.∣ refl _ ∣
Fundamental-group′[K1]≃ᴳ :
{G : Group g} →
Univalence g →
(s : Is-set (proj₁ (Ω (K[ G ]1 , base)))) →
Fundamental-group′ (K[ G ]1 , base) s ≃ᴳ G
Fundamental-group′[K1]≃ᴳ {g} {G} univ _ = λ where
.related → equiv
.homomorphic → hom
where
module FG = Group (Fundamental-group′ (K[ G ]1 , base) is-groupoid)
open Group G
to-≃ : Carrier → Carrier ≃ Carrier
to-≃ x = Eq.↔→≃
(_∘ x)
(_∘ x ⁻¹)
(λ y →
(y ∘ x ⁻¹) ∘ x ≡⟨ sym $ assoc _ _ _ ⟩
y ∘ (x ⁻¹ ∘ x) ≡⟨ cong (y ∘_) $ left-inverse _ ⟩
y ∘ id ≡⟨ right-identity _ ⟩∎
y ∎)
(λ y →
(y ∘ x) ∘ x ⁻¹ ≡⟨ sym $ assoc _ _ _ ⟩
y ∘ (x ∘ x ⁻¹) ≡⟨ cong (y ∘_) $ right-inverse _ ⟩
y ∘ id ≡⟨ right-identity _ ⟩∎
y ∎)
Code : K[ G ]1 → Set g
Code = rec λ where
.is-groupoidʳ → ∃-H-level-H-level-1+ ext univ 2
.baseʳ → Carrier , Carrier-is-set
.loopʳ x → Σ-≡,≡→≡ (≃⇒≡ univ (to-≃ x))
(H-level-propositional ext 2 _ _)
.loop-idʳ →
Σ-≡,≡→≡ (≃⇒≡ univ (to-≃ id)) _ ≡⟨ _≃_.from (Eq.≃-≡ $ Eq.↔⇒≃ B.Σ-≡,≡↔≡) $
Σ-≡,≡→≡
(
≃⇒≡ univ (to-≃ id) ≡⟨ cong (≃⇒≡ univ) $ Eq.lift-equality ext $ ⟨ext⟩
right-identity ⟩
≃⇒≡ univ Eq.id ≡⟨ ≃⇒≡-id univ ⟩∎
refl _ ∎)
(H-level.⇒≡ 1 (H-level-propositional ext 2) _ _) ⟩
Σ-≡,≡→≡ (refl _) (subst-refl _ _) ≡⟨ Σ-≡,≡→≡-refl-subst-refl ⟩∎
refl _ ∎
.loop-∘ʳ {x} {y} →
Σ-≡,≡→≡ (≃⇒≡ univ (to-≃ (x ∘ y))) _ ≡⟨ _≃_.from (Eq.≃-≡ $ Eq.↔⇒≃ B.Σ-≡,≡↔≡) $
Σ-≡,≡→≡
(
≃⇒≡ univ (to-≃ (x ∘ y)) ≡⟨ (cong (≃⇒≡ univ) $ Eq.lift-equality ext $ ⟨ext⟩ λ _ →
assoc _ _ _) ⟩
≃⇒≡ univ (to-≃ y Eq.∘ to-≃ x) ≡⟨ ≃⇒≡-∘ univ ext _ _ ⟩∎
trans (≃⇒≡ univ (to-≃ x)) (≃⇒≡ univ (to-≃ y)) ∎)
(H-level.⇒≡ 1 (H-level-propositional ext 2) _ _) ⟩
Σ-≡,≡→≡ (trans (≃⇒≡ univ (to-≃ x)) (≃⇒≡ univ (to-≃ y))) _ ≡⟨ sym $ trans-Σ-≡,≡→≡ _ _ _ _ ⟩∎
trans (Σ-≡,≡→≡ (≃⇒≡ univ (to-≃ x)) _)
(Σ-≡,≡→≡ (≃⇒≡ univ (to-≃ y)) _) ∎
≡⇒≃-cong-Code-loop :
≡⇒≃ (cong (proj₁ ⊚ Code) (loop x)) ≡ to-≃ x
≡⇒≃-cong-Code-loop {x} =
≡⇒≃ (cong (proj₁ ⊚ Code) (loop x)) ≡⟨ cong ≡⇒≃ $ sym $ cong-∘ proj₁ Code (loop x) ⟩
≡⇒≃ (cong proj₁ (cong Code (loop x))) ≡⟨ cong (≡⇒≃ ⊚ cong proj₁) rec-loop ⟩
≡⇒≃ (cong proj₁ $
Σ-≡,≡→≡ (≃⇒≡ univ (to-≃ x))
(H-level-propositional ext 2 _ _)) ≡⟨ cong ≡⇒≃ $ proj₁-Σ-≡,≡→≡ _ _ ⟩
≡⇒≃ (≃⇒≡ univ (to-≃ x)) ≡⟨ _≃_.right-inverse-of (≡≃≃ univ) _ ⟩∎
to-≃ x ∎
subst-Code-loop :
subst (proj₁ ⊚ Code) (loop x) ≡ _∘ x
subst-Code-loop {x} = ⟨ext⟩ λ y →
subst (proj₁ ⊚ Code) (loop x) y ≡⟨ subst-in-terms-of-≡⇒↝ equivalence _ _ _ ⟩
_≃_.to (≡⇒≃ (cong (proj₁ ⊚ Code) (loop x))) y ≡⟨ cong (λ eq → _≃_.to eq y) ≡⇒≃-cong-Code-loop ⟩∎
_≃_.to (to-≃ x) y ∎
subst-Code-sym-loop :
subst (proj₁ ⊚ Code) (sym (loop x)) ≡ _∘ x ⁻¹
subst-Code-sym-loop {x} = ⟨ext⟩ λ y →
subst (proj₁ ⊚ Code) (sym (loop x)) y ≡⟨ subst-in-terms-of-inverse∘≡⇒↝ equivalence _ _ _ ⟩
_≃_.from (≡⇒≃ (cong (proj₁ ⊚ Code) (loop x))) y ≡⟨ cong (λ eq → _≃_.from eq y) ≡⇒≃-cong-Code-loop ⟩∎
_≃_.from (to-≃ x) y ∎
to : base ≡ x → proj₁ (Code x)
to eq = subst (proj₁ ⊚ Code) eq id
from : ∀ x → proj₁ (Code x) → base ≡ x
from = elim-set λ where
.is-setʳ _ → Π-closure ext 2 λ _ →
is-groupoid
.baseʳ → loop
.loopʳ x → ⟨ext⟩ λ y →
subst (λ x → proj₁ (Code x) → base ≡ x) (loop x) loop y ≡⟨ subst-→ ⟩
subst (base ≡_) (loop x)
(loop (subst (proj₁ ⊚ Code) (sym (loop x)) y)) ≡⟨ sym trans-subst ⟩
trans (loop (subst (proj₁ ⊚ Code) (sym (loop x)) y)) (loop x) ≡⟨ cong (flip trans (loop x) ⊚ loop ⊚ (_$ y))
subst-Code-sym-loop ⟩
trans (loop (y ∘ x ⁻¹)) (loop x) ≡⟨ cong (flip trans _) loop-∘ ⟩
trans (trans (loop y) (loop (x ⁻¹))) (loop x) ≡⟨ trans-assoc _ _ _ ⟩
trans (loop y) (trans (loop (x ⁻¹)) (loop x)) ≡⟨ cong (trans _) $ sym loop-∘ ⟩
trans (loop y) (loop (x ⁻¹ ∘ x)) ≡⟨ cong (trans (loop y) ⊚ loop) $ left-inverse _ ⟩
trans (loop y) (loop id) ≡⟨ cong (trans _) loop-id ⟩
trans (loop y) (refl base) ≡⟨ trans-reflʳ _ ⟩∎
loop y ∎
to-loop : ∀ x → to (loop x) ≡ x
to-loop x =
subst (proj₁ ⊚ Code) (loop x) id ≡⟨ cong (_$ id) subst-Code-loop ⟩
id ∘ x ≡⟨ left-identity _ ⟩∎
x ∎
from-to : ∀ eq → from x (to eq) ≡ eq
from-to = elim¹ (λ {x} eq → from x (to eq) ≡ eq)
(loop (subst (proj₁ ⊚ Code) (refl base) id) ≡⟨ cong loop $ subst-refl _ _ ⟩
loop id ≡⟨ loop-id ⟩∎
refl base ∎)
equiv : proj₁ (Ω (K[ G ]1 , base)) ≃ Carrier
equiv =
base ≡ base ↝⟨ Eq.↔→≃ to loop to-loop from-to ⟩□
Carrier □
hom′ :
∀ x y →
_≃_.from equiv (x ∘ y) ≡
_≃_.from equiv x FG.∘ _≃_.from equiv y
hom′ x y =
loop (x ∘ y) ≡⟨ loop-∘ ⟩∎
trans (loop x) (loop y) ∎
hom :
∀ p q →
_≃_.to equiv (p FG.∘ q) ≡
_≃_.to equiv p ∘ _≃_.to equiv q
hom p q = _≃_.from-to equiv
(_≃_.from equiv (_≃_.to equiv p ∘ _≃_.to equiv q) ≡⟨ hom′ _ _ ⟩
_≃_.from equiv (_≃_.to equiv p) FG.∘
_≃_.from equiv (_≃_.to equiv q) ≡⟨ cong₂ FG._∘_
(_≃_.left-inverse-of equiv p)
(_≃_.left-inverse-of equiv q) ⟩∎
p FG.∘ q ∎)
_ :
{G : Group g} {univ : Univalence g} {s : Is-set _} →
_≃_.from (Fundamental-group′[K1]≃ᴳ {G = G} univ s .related) ≡
loop
_ = refl _
Fundamental-group[K1]≃ᴳ :
{G : Group g} →
Univalence g →
Fundamental-group (K[ G ]1 , base) ≃ᴳ G
Fundamental-group[K1]≃ᴳ univ =
↝ᴳ-trans (≃ᴳ-sym Homotopy-group-[1+]′≃ᴳHomotopy-group-[1+])
(Fundamental-group′[K1]≃ᴳ univ is-groupoid)
Abelian→Abelian-Fundamental-group′ :
Abelian G → Abelian (Fundamental-group′ (K[ G ]1 , base) is-groupoid)
Abelian→Abelian-Fundamental-group′ {G} abelian =
flip $ EG.Transitivity-commutative.commutative base _∙_ ∙-base base-∙
where
open Group G
lemma : Carrier → (x : K[ G ]1) → x ≡ x
lemma g₁ = elim-set λ where
.is-setʳ → λ _ → is-groupoid
.baseʳ → loop g₁
.loopʳ g₂ → ≡⇒↝ _ (sym [subst≡]≡[trans≡trans])
(trans (loop g₁) (loop g₂) ≡⟨ sym loop-∘ ⟩
loop (g₁ ∘ g₂) ≡⟨ cong loop (abelian g₁ g₂) ⟩
loop (g₂ ∘ g₁) ≡⟨ loop-∘ ⟩∎
trans (loop g₂) (loop g₁) ∎)
lemma-id : ∀ x → lemma id x ≡ refl x
lemma-id = elim-prop λ where
.is-propositionʳ _ → is-groupoid
.baseʳ →
loop id ≡⟨ loop-id ⟩∎
refl base ∎
lemma-∘ :
∀ g₁ g₂ x → lemma (g₁ ∘ g₂) x ≡ trans (lemma g₁ x) (lemma g₂ x)
lemma-∘ g₁ g₂ = elim-prop λ where
.is-propositionʳ _ → is-groupoid
.baseʳ →
loop (g₁ ∘ g₂) ≡⟨ loop-∘ ⟩∎
trans (loop g₁) (loop g₂) ∎
_∙_ : K[ G ]1 → K[ G ]1 → K[ G ]1
_∙_ x = rec λ where
.is-groupoidʳ → is-groupoid
.baseʳ → x
.loopʳ g → lemma g x
.loop-idʳ → lemma-id x
.loop-∘ʳ → lemma-∘ _ _ x
base-∙ : ∀ x → x ∙ base ≡ x
base-∙ _ = refl _
∙-base : ∀ y → base ∙ y ≡ y
∙-base = elim-set λ where
.is-setʳ _ → is-groupoid
.baseʳ → refl _
.loopʳ y →
subst (λ y → base ∙ y ≡ y) (loop y) (refl _) ≡⟨ subst-in-terms-of-trans-and-cong ⟩
trans (sym (cong (base ∙_) (loop y)))
(trans (refl _) (cong P.id (loop y))) ≡⟨ cong (trans _) $
trans (trans-reflˡ _) $
sym $ cong-id _ ⟩
trans (sym (cong (base ∙_) (loop y))) (loop y) ≡⟨ cong (flip trans (loop y) ⊚ sym) $
rec-loop ⟩
trans (sym (loop y)) (loop y) ≡⟨ trans-symˡ _ ⟩∎
refl _ ∎
K[Fundamental-group′]1↣ᴮ :
{P : Pointed-type p} {s : Is-set (proj₁ (Ω P))} →
Univalence p →
H-level 3 (proj₁ P) →
(K[ Fundamental-group′ P s ]1 , base) ↝[ embedding ]ᴮ P
K[Fundamental-group′]1↣ᴮ {P = P@(A , a)} {s} univ g =
record { to = to; is-embedding = emb } , refl _
where
to : K[ Fundamental-group′ P s ]1 → A
to = rec λ where
.baseʳ → a
.loopʳ → P.id
.loop-idʳ → refl _
.loop-∘ʳ → refl _
.is-groupoidʳ → g
iso :
Fundamental-group′ P s ≃ᴳ
Fundamental-group′ (K[ Fundamental-group′ P s ]1 , base) is-groupoid
iso = ≃ᴳ-sym $ Fundamental-group′[K1]≃ᴳ univ is-groupoid
cong-to-iso : cong to ⊚ Homomorphic.to iso ≡ P.id
cong-to-iso = ⟨ext⟩ λ eq →
cong to (loop eq) ≡⟨ rec-loop ⟩∎
eq ∎
cong-to-equivalence :
Eq.Is-equivalence (cong {x = base} {y = base} to)
cong-to-equivalence = Eq.Two-out-of-three.g∘f-f
(Eq.two-out-of-three _ _)
(Is-equivalence-cong _ (ext⁻¹ (sym cong-to-iso))
(_≃_.is-equivalence Eq.id))
(_≃_.is-equivalence (iso .related))
emb : Is-embedding to
emb = elim-prop λ where
.is-propositionʳ _ →
Π-closure ext 1 λ _ →
Is-equivalence-propositional ext
.baseʳ → elim-prop λ where
.is-propositionʳ _ → Is-equivalence-propositional ext
.baseʳ → cong-to-equivalence
K[Fundamental-group′]1≃ᴮ :
{P : Pointed-type p} {s : Is-set (proj₁ (Ω P))} →
Univalence p →
H-level 3 (proj₁ P) →
Connected P →
(K[ Fundamental-group′ P s ]1 , base) ≃ᴮ P
K[Fundamental-group′]1≃ᴮ {P = P@(A , a)} {s} univ g conn =
Eq.⟨ Embedding.to (proj₁ f)
, _≃_.to TP.surjective×embedding≃equivalence
(surj , Embedding.is-embedding (proj₁ f)) ⟩
, proj₂ f
where
f = K[Fundamental-group′]1↣ᴮ univ g
surj : Surjective (Embedding.to (proj₁ f))
surj x = flip TP.∥∥-map (conn x) λ a≡x →
base
, (Embedding.to (proj₁ f) base ≡⟨⟩
a ≡⟨ a≡x ⟩∎
x ∎)
Fundamental-group′[K1≃K1]≃ᴳ :
{G : Group g} {s : Is-set _} →
Univalence g →
Abelian G →
Fundamental-group′ ((K[ G ]1 ≃ K[ G ]1) , Eq.id) s ≃ᴳ G
Fundamental-group′[K1≃K1]≃ᴳ {G} univ abelian = λ where
.related →
_≡_ {A = K[ G ]1 ≃ K[ G ]1} Eq.id Eq.id ↝⟨ inverse $ ≃-to-≡≃≡ ext ext ⟩
((x : K[ G ]1) → x ≡ x) ↝⟨ Eq.↔→≃ to from to-from from-to ⟩□
Carrier □
.homomorphic p q →
Homomorphic.to iso (cong (λ eq → _≃_.to eq base) (trans p q)) ≡⟨ cong (Homomorphic.to iso) $
cong-trans _ _ _ ⟩
Homomorphic.to iso
(trans (cong (λ eq → _≃_.to eq base) p)
(cong (λ eq → _≃_.to eq base) q)) ≡⟨ Homomorphic.homomorphic iso _ _ ⟩∎
Homomorphic.to iso (cong (λ eq → _≃_.to eq base) p) ∘
Homomorphic.to iso (cong (λ eq → _≃_.to eq base) q) ∎
where
open Group G
iso = Fundamental-group′[K1]≃ᴳ {G = G} univ is-groupoid
to : ((x : K[ G ]1) → x ≡ x) → Carrier
to f = Homomorphic.to iso (f base)
from : Carrier → (x : K[ G ]1) → x ≡ x
from x = elim-set λ where
.is-setʳ _ → is-groupoid
.baseʳ → loop x
.loopʳ y → ≡⇒↝ _ (sym [subst≡]≡[trans≡trans])
(trans (loop x) (loop y) ≡⟨ sym loop-∘ ⟩
loop (x ∘ y) ≡⟨ cong loop $ abelian x y ⟩
loop (y ∘ x) ≡⟨ loop-∘ ⟩∎
trans (loop y) (loop x) ∎)
to-from : ∀ p → to (from p) ≡ p
to-from x =
Homomorphic.to iso (loop x) ≡⟨ _≃_.right-inverse-of (Homomorphic.related iso) _ ⟩∎
x ∎
from-to : ∀ f → from (to f) ≡ f
from-to f = ⟨ext⟩ $ elim-prop λ where
.is-propositionʳ _ → is-groupoid
.baseʳ →
loop (Homomorphic.to iso (f base)) ≡⟨ _≃_.left-inverse-of (Homomorphic.related iso) _ ⟩∎
f base ∎