3d0d0947d6
some of the changes are backported from the hott3 library pi_pathover and pi_pathover' are interchanged (same for variants and for sigma) various definitions received explicit arguments: pinverse and eq_equiv_homotopy and ***.sigma_char eq_of_fn_eq_fn is renamed to inj in definitions about higher loop spaces and homotopy groups, the natural number arguments are now consistently before the type arguments
388 lines
14 KiB
Text
388 lines
14 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, Jakob von Raumer
|
|
|
|
Declaration and properties of the pushout
|
|
-/
|
|
|
|
import .quotient types.sigma types.arrow_2
|
|
|
|
open quotient eq sum equiv is_trunc pointed
|
|
|
|
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 inj_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)
|
|
|
|
protected theorem elim_inl {P : Type} (Pinl : BL → P) (Pinr : TR → P)
|
|
(Pglue : Π(x : TL), Pinl (f x) = Pinr (g x)) {b b' : BL} (p : b = b')
|
|
: ap (pushout.elim Pinl Pinr Pglue) (ap inl p) = ap Pinl p :=
|
|
!ap_compose⁻¹
|
|
|
|
protected theorem elim_inr {P : Type} (Pinl : BL → P) (Pinr : TR → P)
|
|
(Pglue : Π(x : TL), Pinl (f x) = Pinr (g x)) {b b' : TR} (p : b = b')
|
|
: ap (pushout.elim Pinl Pinr Pglue) (ap inr p) = ap Pinr p :=
|
|
!ap_compose⁻¹
|
|
|
|
/- 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 [unfold 6] : 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 [constructor] : 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 [unfold 16] : 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 [unfold 18] {x x' : BL} (p : x = x')
|
|
: ap (pushout.functor tl bl tr fh gh) (ap inl p) = ap inl (ap bl p) :=
|
|
by cases p; reflexivity
|
|
|
|
protected definition ap_functor_inr [unfold 18] {x x' : TR} (p : x = x')
|
|
: ap (pushout.functor 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] [constructor]
|
|
: is_equiv (pushout.functor tl bl tr fh gh) :=
|
|
adjointify
|
|
(pushout.functor tl bl tr fh gh)
|
|
(pushout.functor 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 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 tl⁻¹ bl⁻¹ tr⁻¹ _ _)
|
|
(pushout.functor 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 [constructor] : pushout f g ≃ pushout f' g' :=
|
|
equiv.mk (pushout.functor tl bl tr fh gh) _
|
|
end
|
|
|
|
definition pointed_pushout [instance] [constructor] {TL BL TR : Type} [HTL : pointed TL]
|
|
[HBL : pointed BL] [HTR : pointed TR] (f : TL → BL) (g : TL → TR) : pointed (pushout f g) :=
|
|
pointed.mk (inl (point _))
|
|
end pushout open pushout
|
|
|
|
definition ppushout [constructor] {TL BL TR : Type*} (f : TL →* BL) (g : TL →* TR) : Type* :=
|
|
pointed.mk' (pushout f g)
|
|
|
|
namespace pushout
|
|
section
|
|
parameters {TL BL TR : Type*} (f : TL →* BL) (g : TL →* TR)
|
|
|
|
parameters {f g}
|
|
definition pinl [constructor] : BL →* ppushout f g :=
|
|
pmap.mk inl idp
|
|
|
|
definition pinr [constructor] : TR →* ppushout f g :=
|
|
pmap.mk inr ((ap inr (respect_pt g))⁻¹ ⬝ !glue⁻¹ ⬝ (ap inl (respect_pt f)))
|
|
|
|
definition pglue (x : TL) : pinl (f x) = pinr (g x) := -- TODO do we need this?
|
|
!glue
|
|
|
|
end
|
|
|
|
section
|
|
variables {TL BL TR : Type*} (f : TL →* BL) (g : TL →* TR)
|
|
|
|
protected definition psymm [constructor] : ppushout f g ≃* ppushout g f :=
|
|
begin
|
|
fapply pequiv_of_equiv,
|
|
{ apply pushout.symm },
|
|
{ exact ap inr (respect_pt f)⁻¹ ⬝ !glue⁻¹ ⬝ ap inl (respect_pt g) }
|
|
end
|
|
|
|
end
|
|
end pushout
|