{-# OPTIONS --safe --lossy-unification #-} module Cubical.Homotopy.EilenbergMacLane.Base where open import Cubical.Foundations.Prelude open import Cubical.Foundations.Isomorphism open import Cubical.Foundations.Equiv open import Cubical.Foundations.Equiv.HalfAdjoint open import Cubical.Foundations.GroupoidLaws renaming (assoc to ∙assoc) open import Cubical.Foundations.Path open import Cubical.Foundations.HLevels open import Cubical.Foundations.Univalence open import Cubical.Foundations.Pointed open import Cubical.Foundations.Transport open import Cubical.Data.Unit open import Cubical.Data.Sigma open import Cubical.Algebra.Group.Base open import Cubical.Algebra.Group.Properties open import Cubical.Homotopy.Connected open import Cubical.HITs.Truncation as Trunc renaming (rec to trRec; rec2 to trRec2 ; elim to trElim) hiding (elim2) open import Cubical.HITs.EilenbergMacLane1 hiding (elim) open import Cubical.Algebra.AbGroup.Base open import Cubical.Data.Empty renaming (rec to ⊥-rec) hiding (elim) open import Cubical.Data.Nat hiding (_·_ ; elim) open import Cubical.HITs.Susp open import Cubical.Functions.Morphism open import Cubical.Foundations.Path private variable ℓ ℓ' : Level _* = AbGroup→Group EM-raw : (G : AbGroup ℓ) (n : ℕ) → Type ℓ EM-raw G zero = fst G EM-raw G (suc zero) = EM₁ (G *) EM-raw G (suc (suc n)) = Susp (EM-raw G (suc n)) EM-raw' : ∀ {ℓ} (G : AbGroup ℓ) (n : ℕ) → Type ℓ EM-raw' G zero = fst G EM-raw' G (suc zero) = EM₁-raw (AbGroup→Group G) EM-raw' G (suc (suc n)) = EM-raw G (suc (suc n)) ptEM-raw : {n : ℕ} {G : AbGroup ℓ} → EM-raw G n ptEM-raw {n = zero} {G = G} = AbGroupStr.0g (snd G) ptEM-raw {n = suc zero} {G = G} = embase ptEM-raw {n = suc (suc n)} {G = G} = north raw-elim : (G : AbGroup ℓ) (n : ℕ) {A : EM-raw G (suc n) → Type ℓ'} → ((x : _) → isOfHLevel (suc n) (A x) ) → A ptEM-raw → (x : _) → A x raw-elim G zero hlev b = elimProp _ hlev b raw-elim G (suc n) hlev b north = b raw-elim G (suc n) {A = A} hlev b south = subst A (merid ptEM-raw) b raw-elim G (suc n) {A = A} hlev b (merid a i) = help a i where help : (a : _) → PathP (λ i → A (merid a i)) b (subst A (merid ptEM-raw) b) help = raw-elim G n (λ _ → isOfHLevelPathP' (suc n) (hlev _) _ _) λ i → transp (λ j → A (merid ptEM-raw (j ∧ i))) (~ i) b EM : (G : AbGroup ℓ) (n : ℕ) → Type ℓ EM G zero = EM-raw G zero EM G (suc zero) = EM-raw G 1 EM G (suc (suc n)) = hLevelTrunc (4 + n) (EM-raw G (suc (suc n))) 0ₖ : {G : AbGroup ℓ} (n : ℕ) → EM G n 0ₖ {G = G} zero = AbGroupStr.0g (snd G) 0ₖ (suc zero) = embase 0ₖ (suc (suc n)) = ∣ ptEM-raw ∣ EM∙ : (G : AbGroup ℓ) (n : ℕ) → Pointed ℓ EM∙ G n = EM G n , (0ₖ n) EM-raw∙ : (G : AbGroup ℓ) (n : ℕ) → Pointed ℓ EM-raw∙ G n = EM-raw G n , ptEM-raw EM-raw'∙ : ∀ {ℓ} (G : AbGroup ℓ) (n : ℕ) → Pointed ℓ fst (EM-raw'∙ G n) = EM-raw' G n snd (EM-raw'∙ G zero) = AbGroupStr.0g (snd G) snd (EM-raw'∙ G (suc zero)) = embase-raw snd (EM-raw'∙ G (suc (suc n))) = north hLevelEM : (G : AbGroup ℓ) (n : ℕ) → isOfHLevel (2 + n) (EM G n) hLevelEM G zero = AbGroupStr.is-set (snd G) hLevelEM G (suc zero) = emsquash hLevelEM G (suc (suc n)) = isOfHLevelTrunc (4 + n) EM-raw→EM : (G : AbGroup ℓ) (n : ℕ) → EM-raw G n → EM G n EM-raw→EM G zero x = x EM-raw→EM G (suc zero) x = x EM-raw→EM G (suc (suc n)) = ∣_∣ elim : {G : AbGroup ℓ} (n : ℕ) {A : EM G n → Type ℓ'} → ((x : _) → isOfHLevel (2 + n) (A x)) → ((x : EM-raw G n) → A (EM-raw→EM G n x)) → (x : _) → A x elim zero hlev hyp x = hyp x elim (suc zero) hlev hyp x = hyp x elim (suc (suc n)) hlev hyp = trElim (λ _ → hlev _) hyp elim2 : ∀ {ℓ''}{G : AbGroup ℓ} {H : AbGroup ℓ'} (n : ℕ) {A : EM G n → EM H n → Type ℓ''} → ((x : _) (y : _) → isOfHLevel (2 + n) (A x y)) → ((x : EM-raw G n) (y : EM-raw H n) → A (EM-raw→EM G n x) (EM-raw→EM H n y)) → (x : _) (y : _) → A x y elim2 n hlev ind = elim n (λ _ → isOfHLevelΠ (2 + n) (λ _ → hlev _ _)) λ x → elim n (λ _ → hlev _ _) (ind x) EM-raw'→EM : ∀ {ℓ} (G : AbGroup ℓ) (n : ℕ) → EM-raw' G n → EM G n EM-raw'→EM G zero x = x EM-raw'→EM G (suc zero) x = EM₁-raw→EM₁ _ x EM-raw'→EM G (suc (suc n)) x = ∣ x ∣ₕ EM-raw'→EM∙ : ∀ {ℓ} (G : AbGroup ℓ) (n : ℕ) → EM-raw'→EM G n (EM-raw'∙ G n .snd) ≡ EM∙ G n .snd EM-raw'→EM∙ G zero = refl EM-raw'→EM∙ G (suc zero) = refl EM-raw'→EM∙ G (suc (suc n)) = refl EM-raw'-elim : ∀ {ℓ ℓ'} (G : AbGroup ℓ) (n : ℕ) {B : EM G n → Type ℓ'} → ((x : _) → isOfHLevel (suc n) (B x)) → ((x : EM-raw' G n) → (B (EM-raw'→EM _ _ x))) → (x : _ ) → B x EM-raw'-elim G zero {B = B} hlev ind = ind EM-raw'-elim G (suc zero) {B = B} hlev ind = elimSet _ hlev (ind embase-raw) λ g → cong ind (emloop-raw g) EM-raw'-elim G (suc (suc n)) {B = B} hlev ind = Trunc.elim (λ _ → isOfHLevelSuc (3 + n) (hlev _)) ind EM-raw'-trivElim : (G : AbGroup ℓ) (n : ℕ) {A : EM-raw' G (suc n) → Type ℓ'} → ((x : _) → isOfHLevel (suc n) (A x) ) → A (snd (EM-raw'∙ G (suc n))) → (x : _) → A x EM-raw'-trivElim G zero {A = A} prop x embase-raw = x EM-raw'-trivElim G zero {A = A} prop x (emloop-raw g i) = isProp→PathP {B = λ i → A (emloop-raw g i)} (λ _ → prop _) x x i EM-raw'-trivElim G (suc n) {A = A} = raw-elim G (suc n) EM→Prop : (G : AbGroup ℓ) (n : ℕ) {A : EM G (suc n) → Type ℓ'} → ((x : _) → isProp (A x) ) → A (0ₖ (suc n)) → (x : _) → A x EM→Prop G zero {A = A} p h = elimProp (AbGroup→Group G) p h EM→Prop G (suc n) {A = A} p h = Trunc.elim (λ _ → isProp→isOfHLevelSuc (suc (suc (suc n))) (p _)) (suspToPropElim ptEM-raw (λ _ → p _) h)