52dd6cf90b
This commit adds truncated 2-quotients, groupoid quotients, Eilenberg MacLane spaces, chain complexes, the long exact sequence of homotopy groups, the Freudenthal Suspension Theorem, Whitehead's principle, and the computation of homotopy groups of almost all spheres which are known in HoTT.
342 lines
13 KiB
Text
342 lines
13 KiB
Text
/-
|
|
Copyright (c) 2015-16 Floris van Doorn. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
Authors: Floris van Doorn, Ulrik Buchholtz
|
|
|
|
Declaration and properties of the pushout
|
|
-/
|
|
|
|
import .quotient types.sigma types.arrow_2
|
|
|
|
open quotient eq sum equiv is_trunc
|
|
|
|
namespace pushout
|
|
section
|
|
|
|
parameters {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
|
|
|
|
local abbreviation A := BL + TR
|
|
inductive pushout_rel : A → A → Type :=
|
|
| Rmk : Π(x : TL), pushout_rel (inl (f x)) (inr (g x))
|
|
open pushout_rel
|
|
local abbreviation R := pushout_rel
|
|
|
|
definition pushout : Type := quotient R -- TODO: define this in root namespace
|
|
|
|
parameters {f g}
|
|
definition inl (x : BL) : pushout :=
|
|
class_of R (inl x)
|
|
|
|
definition inr (x : TR) : pushout :=
|
|
class_of R (inr x)
|
|
|
|
definition glue (x : TL) : inl (f x) = inr (g x) :=
|
|
eq_of_rel pushout_rel (Rmk f g x)
|
|
|
|
protected definition rec {P : pushout → Type} (Pinl : Π(x : BL), P (inl x))
|
|
(Pinr : Π(x : TR), P (inr x)) (Pglue : Π(x : TL), Pinl (f x) =[glue x] Pinr (g x))
|
|
(y : pushout) : P y :=
|
|
begin
|
|
induction y,
|
|
{ cases a,
|
|
apply Pinl,
|
|
apply Pinr},
|
|
{ cases H, apply Pglue}
|
|
end
|
|
|
|
protected definition rec_on [reducible] {P : pushout → Type} (y : pushout)
|
|
(Pinl : Π(x : BL), P (inl x)) (Pinr : Π(x : TR), P (inr x))
|
|
(Pglue : Π(x : TL), Pinl (f x) =[glue x] Pinr (g x)) : P y :=
|
|
rec Pinl Pinr Pglue y
|
|
|
|
theorem rec_glue {P : pushout → Type} (Pinl : Π(x : BL), P (inl x))
|
|
(Pinr : Π(x : TR), P (inr x)) (Pglue : Π(x : TL), Pinl (f x) =[glue x] Pinr (g x))
|
|
(x : TL) : apd (rec Pinl Pinr Pglue) (glue x) = Pglue x :=
|
|
!rec_eq_of_rel
|
|
|
|
protected definition elim {P : Type} (Pinl : BL → P) (Pinr : TR → P)
|
|
(Pglue : Π(x : TL), Pinl (f x) = Pinr (g x)) (y : pushout) : P :=
|
|
rec Pinl Pinr (λx, pathover_of_eq (Pglue x)) y
|
|
|
|
protected definition elim_on [reducible] {P : Type} (y : pushout) (Pinl : BL → P)
|
|
(Pinr : TR → P) (Pglue : Π(x : TL), Pinl (f x) = Pinr (g x)) : P :=
|
|
elim Pinl Pinr Pglue y
|
|
|
|
theorem elim_glue {P : Type} (Pinl : BL → P) (Pinr : TR → P)
|
|
(Pglue : Π(x : TL), Pinl (f x) = Pinr (g x)) (x : TL)
|
|
: ap (elim Pinl Pinr Pglue) (glue x) = Pglue x :=
|
|
begin
|
|
apply eq_of_fn_eq_fn_inv !(pathover_constant (glue x)),
|
|
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑pushout.elim,rec_glue],
|
|
end
|
|
|
|
protected definition elim_type (Pinl : BL → Type) (Pinr : TR → Type)
|
|
(Pglue : Π(x : TL), Pinl (f x) ≃ Pinr (g x)) : pushout → Type :=
|
|
quotient.elim_type (sum.rec Pinl Pinr)
|
|
begin intro v v' r, induction r, apply Pglue end
|
|
|
|
protected definition elim_type_on [reducible] (y : pushout) (Pinl : BL → Type)
|
|
(Pinr : TR → Type) (Pglue : Π(x : TL), Pinl (f x) ≃ Pinr (g x)) : Type :=
|
|
elim_type Pinl Pinr Pglue y
|
|
|
|
theorem elim_type_glue (Pinl : BL → Type) (Pinr : TR → Type)
|
|
(Pglue : Π(x : TL), Pinl (f x) ≃ Pinr (g x)) (x : TL)
|
|
: transport (elim_type Pinl Pinr Pglue) (glue x) = Pglue x :=
|
|
!elim_type_eq_of_rel_fn
|
|
|
|
theorem elim_type_glue_inv (Pinl : BL → Type) (Pinr : TR → Type)
|
|
(Pglue : Π(x : TL), Pinl (f x) ≃ Pinr (g x)) (x : TL)
|
|
: transport (elim_type Pinl Pinr Pglue) (glue x)⁻¹ = to_inv (Pglue x) :=
|
|
!elim_type_eq_of_rel_inv
|
|
|
|
protected definition rec_prop {P : pushout → Type} [H : Πx, is_prop (P x)]
|
|
(Pinl : Π(x : BL), P (inl x)) (Pinr : Π(x : TR), P (inr x)) (y : pushout) :=
|
|
rec Pinl Pinr (λx, !is_prop.elimo) y
|
|
|
|
protected definition elim_prop {P : Type} [H : is_prop P] (Pinl : BL → P) (Pinr : TR → P)
|
|
(y : pushout) : P :=
|
|
elim Pinl Pinr (λa, !is_prop.elim) y
|
|
|
|
end
|
|
end pushout
|
|
|
|
attribute pushout.inl pushout.inr [constructor]
|
|
attribute pushout.rec pushout.elim [unfold 10] [recursor 10]
|
|
attribute pushout.elim_type [unfold 9]
|
|
attribute pushout.rec_on pushout.elim_on [unfold 7]
|
|
attribute pushout.elim_type_on [unfold 6]
|
|
|
|
open sigma
|
|
|
|
namespace pushout
|
|
|
|
variables {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
|
|
|
|
/- The non-dependent universal property -/
|
|
definition pushout_arrow_equiv (C : Type)
|
|
: (pushout f g → C) ≃ (Σ(i : BL → C) (j : TR → C), Πc, i (f c) = j (g c)) :=
|
|
begin
|
|
fapply equiv.MK,
|
|
{ intro f, exact ⟨λx, f (inl x), λx, f (inr x), λx, ap f (glue x)⟩},
|
|
{ intro v x, induction v with i w, induction w with j p, induction x,
|
|
exact (i a), exact (j a), exact (p x)},
|
|
{ intro v, induction v with i w, induction w with j p, esimp,
|
|
apply ap (λp, ⟨i, j, p⟩), apply eq_of_homotopy, intro x, apply elim_glue},
|
|
{ intro f, apply eq_of_homotopy, intro x, induction x: esimp,
|
|
apply eq_pathover, apply hdeg_square, esimp, apply elim_glue},
|
|
end
|
|
|
|
/- glue squares -/
|
|
protected definition glue_square {x x' : TL} (p : x = x')
|
|
: square (glue x) (glue x') (ap inl (ap f p)) (ap inr (ap g p)) :=
|
|
by cases p; apply vrefl
|
|
|
|
end pushout
|
|
|
|
open function sigma.ops
|
|
|
|
namespace pushout
|
|
|
|
/- The flattening lemma -/
|
|
section
|
|
|
|
universe variable u
|
|
parameters {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
|
|
(Pinl : BL → Type.{u}) (Pinr : TR → Type.{u})
|
|
(Pglue : Π(x : TL), Pinl (f x) ≃ Pinr (g x))
|
|
include Pglue
|
|
|
|
local abbreviation A := BL + TR
|
|
local abbreviation R : A → A → Type := pushout_rel f g
|
|
local abbreviation P [unfold 5] := pushout.elim_type Pinl Pinr Pglue
|
|
|
|
local abbreviation F : sigma (Pinl ∘ f) → sigma Pinl :=
|
|
λz, ⟨ f z.1 , z.2 ⟩
|
|
|
|
local abbreviation G : sigma (Pinl ∘ f) → sigma Pinr :=
|
|
λz, ⟨ g z.1 , Pglue z.1 z.2 ⟩
|
|
|
|
protected definition flattening : sigma P ≃ pushout F G :=
|
|
begin
|
|
apply equiv.trans !quotient.flattening.flattening_lemma,
|
|
fapply equiv.MK,
|
|
{ intro q, induction q with z z z' fr,
|
|
{ induction z with a p, induction a with x x,
|
|
{ exact inl ⟨x, p⟩ },
|
|
{ exact inr ⟨x, p⟩ } },
|
|
{ induction fr with a a' r p, induction r with x,
|
|
exact glue ⟨x, p⟩ } },
|
|
{ intro q, induction q with xp xp xp,
|
|
{ exact class_of _ ⟨sum.inl xp.1, xp.2⟩ },
|
|
{ exact class_of _ ⟨sum.inr xp.1, xp.2⟩ },
|
|
{ apply eq_of_rel, constructor } },
|
|
{ intro q, induction q with xp xp xp: induction xp with x p,
|
|
{ apply ap inl, reflexivity },
|
|
{ apply ap inr, reflexivity },
|
|
{ unfold F, unfold G, apply eq_pathover,
|
|
rewrite [ap_id,ap_compose' (quotient.elim _ _)],
|
|
krewrite elim_glue, krewrite elim_eq_of_rel, apply hrefl } },
|
|
{ intro q, induction q with z z z' fr,
|
|
{ induction z with a p, induction a with x x,
|
|
{ reflexivity },
|
|
{ reflexivity } },
|
|
{ induction fr with a a' r p, induction r with x,
|
|
esimp, apply eq_pathover,
|
|
rewrite [ap_id,ap_compose' (pushout.elim _ _ _)],
|
|
krewrite elim_eq_of_rel, krewrite elim_glue, apply hrefl } }
|
|
end
|
|
end
|
|
|
|
-- Commutativity of pushouts
|
|
section
|
|
variables {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
|
|
|
|
protected definition transpose [constructor] : pushout f g → pushout g f :=
|
|
begin
|
|
intro x, induction x, apply inr a, apply inl a, apply !glue⁻¹
|
|
end
|
|
|
|
--TODO prove without krewrite?
|
|
protected definition transpose_involutive (x : pushout f g) :
|
|
pushout.transpose g f (pushout.transpose f g x) = x :=
|
|
begin
|
|
induction x, apply idp, apply idp,
|
|
apply eq_pathover, refine _ ⬝hp !ap_id⁻¹,
|
|
refine !(ap_compose (pushout.transpose _ _)) ⬝ph _, esimp[pushout.transpose],
|
|
krewrite [elim_glue, ap_inv, elim_glue, inv_inv], apply hrfl
|
|
end
|
|
|
|
protected definition symm : pushout f g ≃ pushout g f :=
|
|
begin
|
|
fapply equiv.MK, do 2 exact !pushout.transpose,
|
|
do 2 (intro x; apply pushout.transpose_involutive),
|
|
end
|
|
|
|
end
|
|
|
|
-- Functoriality of pushouts
|
|
section
|
|
section lemmas
|
|
variables {X : Type} {x₀ x₁ x₂ x₃ : X}
|
|
(p : x₀ = x₁) (q : x₁ = x₂) (r : x₂ = x₃)
|
|
private definition is_equiv_functor_lemma₁
|
|
: (r ⬝ ((p ⬝ q ⬝ r)⁻¹ ⬝ p)) = q⁻¹ :=
|
|
by cases p; cases r; cases q; reflexivity
|
|
|
|
private definition is_equiv_functor_lemma₂
|
|
: (p ⬝ q ⬝ r)⁻¹ ⬝ (p ⬝ q) = r⁻¹ :=
|
|
by cases p; cases r; cases q; reflexivity
|
|
end lemmas
|
|
|
|
variables {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
|
|
{TL' BL' TR' : Type} (f' : TL' → BL') (g' : TL' → TR')
|
|
(tl : TL → TL') (bl : BL → BL') (tr : TR → TR')
|
|
(fh : bl ∘ f ~ f' ∘ tl) (gh : tr ∘ g ~ g' ∘ tl)
|
|
include fh gh
|
|
|
|
protected definition functor [reducible] : pushout f g → pushout f' g' :=
|
|
begin
|
|
intro x, induction x with a b z,
|
|
{ exact inl (bl a) },
|
|
{ exact inr (tr b) },
|
|
{ exact (ap inl (fh z)) ⬝ glue (tl z) ⬝ (ap inr (gh z)⁻¹) }
|
|
end
|
|
|
|
protected definition ap_functor_inl [reducible] {x x' : BL} (p : x = x')
|
|
: ap (pushout.functor f g f' g' tl bl tr fh gh) (ap inl p) = ap inl (ap bl p) :=
|
|
by cases p; reflexivity
|
|
|
|
protected definition ap_functor_inr [reducible] {x x' : TR} (p : x = x')
|
|
: ap (pushout.functor f g f' g' tl bl tr fh gh) (ap inr p) = ap inr (ap tr p) :=
|
|
by cases p; reflexivity
|
|
|
|
variables [ietl : is_equiv tl] [iebl : is_equiv bl] [ietr : is_equiv tr]
|
|
include ietl iebl ietr
|
|
|
|
open equiv is_equiv arrow
|
|
protected definition is_equiv_functor [instance]
|
|
: is_equiv (pushout.functor f g f' g' tl bl tr fh gh) :=
|
|
adjointify
|
|
(pushout.functor f g f' g' tl bl tr fh gh)
|
|
(pushout.functor f' g' f g tl⁻¹ bl⁻¹ tr⁻¹
|
|
(inv_commute_of_commute tl bl f f' fh)
|
|
(inv_commute_of_commute tl tr g g' gh))
|
|
abstract begin
|
|
intro x', induction x' with a' b' z',
|
|
{ apply ap inl, apply right_inv },
|
|
{ apply ap inr, apply right_inv },
|
|
{ apply eq_pathover,
|
|
rewrite [ap_id,ap_compose' (pushout.functor f g f' g' tl bl tr fh gh)],
|
|
krewrite elim_glue,
|
|
rewrite [ap_inv,ap_con,ap_inv],
|
|
krewrite [pushout.ap_functor_inr], rewrite ap_con,
|
|
krewrite [pushout.ap_functor_inl,elim_glue],
|
|
apply transpose,
|
|
apply move_top_of_right, apply move_top_of_left',
|
|
krewrite [-(ap_inv inl),-ap_con,-(ap_inv inr),-ap_con],
|
|
apply move_top_of_right, apply move_top_of_left',
|
|
krewrite [-ap_con,-(ap_inv inl),-ap_con],
|
|
rewrite ap_bot_inv_commute_of_commute,
|
|
apply eq_hconcat (ap02 inl
|
|
(is_equiv_functor_lemma₁
|
|
(right_inv bl (f' z'))
|
|
(ap f' (right_inv tl z')⁻¹)
|
|
(fh (tl⁻¹ z'))⁻¹)),
|
|
rewrite [ap_inv f',inv_inv],
|
|
rewrite ap_bot_inv_commute_of_commute,
|
|
refine hconcat_eq _ (ap02 inr
|
|
(is_equiv_functor_lemma₁
|
|
(right_inv tr (g' z'))
|
|
(ap g' (right_inv tl z')⁻¹)
|
|
(gh (tl⁻¹ z'))⁻¹))⁻¹,
|
|
rewrite [ap_inv g',inv_inv],
|
|
apply pushout.glue_square }
|
|
end end
|
|
abstract begin
|
|
intro x, induction x with a b z,
|
|
{ apply ap inl, apply left_inv },
|
|
{ apply ap inr, apply left_inv },
|
|
{ apply eq_pathover,
|
|
rewrite [ap_id,ap_compose'
|
|
(pushout.functor f' g' f g tl⁻¹ bl⁻¹ tr⁻¹ _ _)
|
|
(pushout.functor f g f' g' tl bl tr _ _)],
|
|
krewrite elim_glue,
|
|
rewrite [ap_inv,ap_con,ap_inv],
|
|
krewrite [pushout.ap_functor_inr], rewrite ap_con,
|
|
krewrite [pushout.ap_functor_inl,elim_glue],
|
|
apply transpose,
|
|
apply move_top_of_right, apply move_top_of_left',
|
|
krewrite [-(ap_inv inl),-ap_con,-(ap_inv inr),-ap_con],
|
|
apply move_top_of_right, apply move_top_of_left',
|
|
krewrite [-ap_con,-(ap_inv inl),-ap_con],
|
|
rewrite inv_commute_of_commute_top,
|
|
apply eq_hconcat (ap02 inl
|
|
(is_equiv_functor_lemma₂
|
|
(ap bl⁻¹ (fh z))⁻¹
|
|
(left_inv bl (f z))
|
|
(ap f (left_inv tl z)⁻¹))),
|
|
rewrite [ap_inv f,inv_inv],
|
|
rewrite inv_commute_of_commute_top,
|
|
refine hconcat_eq _ (ap02 inr
|
|
(is_equiv_functor_lemma₂
|
|
(ap tr⁻¹ (gh z))⁻¹
|
|
(left_inv tr (g z))
|
|
(ap g (left_inv tl z)⁻¹)))⁻¹,
|
|
rewrite [ap_inv g,inv_inv],
|
|
apply pushout.glue_square }
|
|
end end
|
|
|
|
end
|
|
|
|
/- version giving the equivalence -/
|
|
section
|
|
variables {TL BL TR : Type} (f : TL → BL) (g : TL → TR)
|
|
{TL' BL' TR' : Type} (f' : TL' → BL') (g' : TL' → TR')
|
|
(tl : TL ≃ TL') (bl : BL ≃ BL') (tr : TR ≃ TR')
|
|
(fh : bl ∘ f ~ f' ∘ tl) (gh : tr ∘ g ~ g' ∘ tl)
|
|
include fh gh
|
|
|
|
protected definition equiv : pushout f g ≃ pushout f' g' :=
|
|
equiv.mk (pushout.functor f g f' g' tl bl tr fh gh) _
|
|
end
|
|
end pushout
|