lean2/hott/hit/pushout.hlean
Floris van Doorn 52dd6cf90b feat(hott): Port files from other repositories to the HoTT library.
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.
2016-05-06 14:27:27 -07:00

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