lean2/hott/homotopy/susp.hlean
Floris van Doorn 2b722b3e34 use psquare for naturality squares consistently
this commit renames some definitions and swaps some arguments around for consistency
2018-09-10 17:59:11 +02:00

525 lines
17 KiB
Text
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2015 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 of suspension
-/
import hit.pushout types.pointed2 cubical.square .connectedness
open pushout unit eq equiv pointed is_equiv
definition susp' (A : Type) : Type := pushout (λ(a : A), star) (λ(a : A), star)
namespace susp
definition north' {A : Type} : susp' A :=
inl star
definition pointed_susp [instance] [constructor] (X : Type)
: pointed (susp' X) :=
pointed.mk north'
end susp open susp
definition susp [constructor] (X : Type) : Type* :=
pointed.MK (susp' X) north'
notation `⅀` := susp
namespace susp
variable {A : Type}
definition north {A : Type} : susp A :=
north'
definition south {A : Type} : susp A :=
inr star
definition merid (a : A) : @north A = @south A :=
glue a
protected definition rec {P : susp A → Type} (PN : P north) (PS : P south)
(Pm : Π(a : A), PN =[merid a] PS) (x : susp' A) : P x :=
begin
induction x with u u,
{ cases u, exact PN},
{ cases u, exact PS},
{ apply Pm},
end
protected definition rec_on [reducible] {P : susp A → Type} (y : susp' A)
(PN : P north) (PS : P south) (Pm : Π(a : A), PN =[merid a] PS) : P y :=
susp.rec PN PS Pm y
theorem rec_merid {P : susp A → Type} (PN : P north) (PS : P south)
(Pm : Π(a : A), PN =[merid a] PS) (a : A)
: apd (susp.rec PN PS Pm) (merid a) = Pm a :=
!rec_glue
protected definition elim {P : Type} (PN : P) (PS : P) (Pm : A → PN = PS)
(x : susp' A) : P :=
susp.rec PN PS (λa, pathover_of_eq _ (Pm a)) x
protected definition elim_on [reducible] {P : Type} (x : susp' A)
(PN : P) (PS : P) (Pm : A → PN = PS) : P :=
susp.elim PN PS Pm x
theorem elim_merid {P : Type} {PN PS : P} (Pm : A → PN = PS) (a : A)
: ap (susp.elim PN PS Pm) (merid a) = Pm a :=
begin
apply inj_inv !(pathover_constant (merid a)),
rewrite [▸*,-apd_eq_pathover_of_eq_ap,↑susp.elim,rec_merid],
end
protected definition elim_type (PN : Type) (PS : Type) (Pm : A → PN ≃ PS)
(x : susp' A) : Type :=
pushout.elim_type (λx, PN) (λx, PS) Pm x
protected definition elim_type_on [reducible] (x : susp' A)
(PN : Type) (PS : Type) (Pm : A → PN ≃ PS) : Type :=
susp.elim_type PN PS Pm x
theorem elim_type_merid (PN : Type) (PS : Type) (Pm : A → PN ≃ PS)
(a : A) : transport (susp.elim_type PN PS Pm) (merid a) = Pm a :=
!elim_type_glue
theorem elim_type_merid_inv {A : Type} (PN : Type) (PS : Type) (Pm : A → PN ≃ PS)
(a : A) : transport (susp.elim_type PN PS Pm) (merid a)⁻¹ = to_inv (Pm a) :=
!elim_type_glue_inv
protected definition merid_square {a a' : A} (p : a = a')
: square (merid a) (merid a') idp idp :=
by cases p; apply vrefl
end susp
attribute susp.north' susp.north susp.south [constructor]
attribute susp.rec susp.elim [unfold 6] [recursor 6]
attribute susp.elim_type [unfold 5]
attribute susp.rec_on susp.elim_on [unfold 3]
attribute susp.elim_type_on [unfold 2]
namespace susp
open is_trunc is_conn trunc
-- Theorem 8.2.1
definition is_conn_susp [instance] (n : trunc_index) (A : Type)
[H : is_conn n A] : is_conn (n .+1) (susp A) :=
is_contr.mk (tr north)
begin
intro x, induction x with x, induction x,
{ reflexivity },
{ exact (trunc.rec (λa, ap tr (merid a)) (center (trunc n A))) },
{ generalize (center (trunc n A)),
intro x, induction x with a',
apply pathover_of_tr_eq,
rewrite [eq_transport_Fr,idp_con],
revert H, induction n with n IH: intro H,
{ apply is_prop.elim },
{ change ap (@tr n .+2 (susp A)) (merid a) = ap tr (merid a'),
generalize a',
apply is_conn_fun.elim n
(is_conn_fun_from_unit n A a)
(λx : A, trunctype.mk' n (ap (@tr n .+2 (susp A)) (merid a) = ap tr (merid x))),
intros,
change ap (@tr n .+2 (susp A)) (merid a) = ap tr (merid a),
reflexivity }
}
end
/- Flattening lemma -/
open prod prod.ops
section
universe variable u
parameters (A : Type) (PN PS : Type.{u}) (Pm : A → PN ≃ PS)
include Pm
local abbreviation P [unfold 5] := susp.elim_type PN PS Pm
local abbreviation F : A × PN → PN := λz, z.2
local abbreviation G : A × PN → PS := λz, Pm z.1 z.2
protected definition flattening : sigma P ≃ pushout F G :=
begin
apply equiv.trans !pushout.flattening,
fapply pushout.equiv,
{ exact sigma.equiv_prod A PN },
{ apply sigma.sigma_unit_left },
{ apply sigma.sigma_unit_left },
{ reflexivity },
{ reflexivity }
end
end
end susp
/- Functoriality and equivalence -/
namespace susp
variables {A B : Type} (f : A → B)
include f
definition susp_functor' [unfold 4] : susp A → susp B :=
begin
intro x, induction x with a,
{ exact north },
{ exact south },
{ exact merid (f a) }
end
variable [Hf : is_equiv f]
include Hf
open is_equiv
protected definition is_equiv_functor [instance] [constructor] : is_equiv (susp_functor' f) :=
adjointify (susp_functor' f) (susp_functor' f⁻¹)
abstract begin
intro sb, induction sb with b, do 2 reflexivity,
apply eq_pathover,
rewrite [ap_id,-ap_compose' (susp_functor' f) (susp_functor' f⁻¹)],
krewrite [susp.elim_merid,susp.elim_merid], apply transpose,
apply susp.merid_square (right_inv f b)
end end
abstract begin
intro sa, induction sa with a, do 2 reflexivity,
apply eq_pathover,
rewrite [ap_id,-ap_compose' (susp_functor' f⁻¹) (susp_functor' f)],
krewrite [susp.elim_merid,susp.elim_merid], apply transpose,
apply susp.merid_square (left_inv f a)
end end
end susp
namespace susp
variables {A B : Type} (f : A ≃ B)
protected definition equiv : susp A ≃ susp B :=
equiv.mk (susp_functor' f) _
end susp
namespace susp
open pointed is_trunc
variables {X X' Y Y' Z : Type*}
definition susp_functor [constructor] (f : X →* Y) : susp X →* susp Y :=
begin
fconstructor,
{ exact susp_functor' f },
{ reflexivity }
end
notation `⅀→`:(max+5) := susp_functor
definition is_equiv_susp_functor [constructor] (f : X →* Y) [Hf : is_equiv f]
: is_equiv (susp_functor f) :=
susp.is_equiv_functor f
definition susp_pequiv [constructor] (f : X ≃* Y) : susp X ≃* susp Y :=
pequiv_of_equiv (susp.equiv f) idp
definition susp_functor_pcompose (g : Y →* Z) (f : X →* Y) :
susp_functor (g ∘* f) ~* susp_functor g ∘* susp_functor f :=
begin
fapply phomotopy.mk,
{ intro x, induction x,
{ reflexivity },
{ reflexivity },
{ apply eq_pathover, apply hdeg_square,
refine !elim_merid ⬝ _ ⬝ (ap_compose (susp_functor g) _ _)⁻¹ᵖ,
refine _ ⬝ ap02 _ !elim_merid⁻¹, exact !elim_merid⁻¹ }},
{ reflexivity },
end
definition susp_functor_phomotopy {f g : X →* Y} (p : f ~* g) :
susp_functor f ~* susp_functor g :=
begin
fapply phomotopy.mk,
{ intro x, induction x,
{ reflexivity },
{ reflexivity },
{ apply eq_pathover, apply hdeg_square, esimp, refine !elim_merid ⬝ _ ⬝ !elim_merid⁻¹ᵖ,
exact ap merid (p a), }},
{ reflexivity },
end
notation `⅀⇒`:(max+5) := susp_functor_phomotopy
definition susp_functor_pid (A : Type*) : susp_functor (pid A) ~* pid (susp A) :=
begin
fapply phomotopy.mk,
{ intro x, induction x,
{ reflexivity },
{ reflexivity },
{ apply eq_pathover_id_right, apply hdeg_square, apply elim_merid }},
{ reflexivity },
end
/- adjunction originally ported from Coq-HoTT,
but we proved some additional naturality conditions -/
definition loop_susp_unit [constructor] (X : Type*) : X →* Ω(susp X) :=
begin
fconstructor,
{ intro x, exact merid x ⬝ (merid pt)⁻¹ },
{ apply con.right_inv },
end
definition loop_susp_unit_natural (f : X →* Y)
: psquare (loop_susp_unit X) (loop_susp_unit Y) f (Ω→ (susp_functor f)) :=
begin
apply ptranspose,
induction X with X x, induction Y with Y y, induction f with f pf, esimp at *, induction pf,
fapply phomotopy.mk,
{ intro x', symmetry,
exact
!ap1_gen_idp_left ⬝
(!ap_con ⬝
whisker_left _ !ap_inv) ⬝
(!elim_merid ◾ (inverse2 !elim_merid)) },
{ rewrite [▸*, idp_con (con.right_inv _)],
apply inv_con_eq_of_eq_con,
refine _ ⬝ !con.assoc',
rewrite inverse2_right_inv,
refine _ ⬝ !con.assoc',
rewrite [ap_con_right_inv],
rewrite [ap1_gen_idp_left_con],
rewrite [-ap_compose (concat idp)] },
end
definition loop_susp_counit [constructor] (X : Type*) : susp (Ω X) →* X :=
begin
fapply pmap.mk,
{ intro x, induction x, exact pt, exact pt, exact a },
{ reflexivity },
end
definition loop_susp_counit_natural (f : X →* Y)
: psquare (loop_susp_counit X) (loop_susp_counit Y) (⅀→ (Ω→ f)) f :=
begin
induction X with X x, induction Y with Y y, induction f with f pf, esimp at *, induction pf,
fconstructor,
{ intro x', induction x' with p,
{ reflexivity },
{ reflexivity },
{ esimp, apply eq_pathover, apply hdeg_square,
xrewrite [-ap_compose' f, -ap_compose' (susp.elim (f x) (f x) (λ (a : f x = f x), a)),▸*],
xrewrite [+elim_merid, ap1_gen_idp_left] }},
{ reflexivity }
end
definition loop_susp_counit_unit (X : Type*)
: ap1 (loop_susp_counit X) ∘* loop_susp_unit (Ω X) ~* pid (Ω X) :=
begin
induction X with X x, fconstructor,
{ intro p, esimp,
refine !ap1_gen_idp_left ⬝
(!ap_con ⬝
whisker_left _ !ap_inv) ⬝
(!elim_merid ◾ inverse2 !elim_merid) },
{ rewrite [▸*,inverse2_right_inv (elim_merid id idp)],
refine !con.assoc ⬝ _,
xrewrite [ap_con_right_inv (susp.elim x x (λa, a)) (merid idp),ap1_gen_idp_left_con,
-ap_compose] }
end
definition loop_susp_unit_counit (X : Type*)
: loop_susp_counit (susp X) ∘* susp_functor (loop_susp_unit X) ~* pid (susp X) :=
begin
induction X with X x, fconstructor,
{ intro x', induction x',
{ reflexivity },
{ exact merid pt },
{ apply eq_pathover,
xrewrite [▸*, ap_id, -ap_compose' (susp.elim north north (λa, a)), +elim_merid,▸*],
apply square_of_eq, exact !idp_con ⬝ !inv_con_cancel_right⁻¹ }},
{ reflexivity }
end
definition susp_elim [constructor] {X Y : Type*} (f : X →* Ω Y) : susp X →* Y :=
loop_susp_counit Y ∘* susp_functor f
definition loop_susp_intro [constructor] {X Y : Type*} (f : susp X →* Y) : X →* Ω Y :=
ap1 f ∘* loop_susp_unit X
definition susp_elim_susp_functor {A B C : Type*} (g : B →* Ω C) (f : A →* B) :
susp_elim g ∘* susp_functor f ~* susp_elim (g ∘* f) :=
begin
refine !passoc ⬝* _, exact pwhisker_left _ !susp_functor_pcompose⁻¹*
end
definition susp_elim_phomotopy {A B : Type*} {f g : A →* Ω B} (p : f ~* g) : susp_elim f ~* susp_elim g :=
pwhisker_left _ (susp_functor_phomotopy p)
definition susp_elim_natural {X Y Z : Type*} (g : Y →* Z) (f : X →* Ω Y)
: g ∘* susp_elim f ~* susp_elim (Ω→ g ∘* f) :=
begin
refine _ ⬝* pwhisker_left _ !susp_functor_pcompose⁻¹*,
refine !passoc⁻¹* ⬝* _ ⬝* !passoc,
exact pwhisker_right _ !loop_susp_counit_natural
end
definition loop_susp_intro_natural {X Y Z : Type*} (g : susp Y →* Z) (f : X →* Y) :
loop_susp_intro (g ∘* susp_functor f) ~* loop_susp_intro g ∘* f :=
pwhisker_right _ !ap1_pcompose ⬝* !passoc ⬝* pwhisker_left _ !loop_susp_unit_natural ⬝*
!passoc⁻¹*
definition susp_adjoint_loop_right_inv {X Y : Type*} (g : X →* Ω Y) :
loop_susp_intro (susp_elim g) ~* g :=
begin
refine !pwhisker_right !ap1_pcompose ⬝* _,
refine !passoc ⬝* _,
refine !pwhisker_left !loop_susp_unit_natural ⬝* _,
refine !passoc⁻¹* ⬝* _,
refine !pwhisker_right !loop_susp_counit_unit ⬝* _,
apply pid_pcompose
end
definition susp_adjoint_loop_left_inv {X Y : Type*} (f : susp X →* Y) :
susp_elim (loop_susp_intro f) ~* f :=
begin
refine !pwhisker_left !susp_functor_pcompose ⬝* _,
refine !passoc⁻¹* ⬝* _,
refine !pwhisker_right !loop_susp_counit_natural⁻¹* ⬝* _,
refine !passoc ⬝* _,
refine !pwhisker_left !loop_susp_unit_counit ⬝* _,
apply pcompose_pid
end
definition susp_adjoint_loop_unpointed [constructor] (X Y : Type*) : susp X →* Y ≃ X →* Ω Y :=
begin
fapply equiv.MK,
{ exact loop_susp_intro },
{ exact susp_elim },
{ intro g, apply eq_of_phomotopy, exact susp_adjoint_loop_right_inv g },
{ intro f, apply eq_of_phomotopy, exact susp_adjoint_loop_left_inv f }
end
definition susp_functor_pconst_homotopy [unfold 3] {X Y : Type*} (x : susp X) :
susp_functor (pconst X Y) x = pt :=
begin
induction x,
{ reflexivity },
{ exact (merid pt)⁻¹ },
{ apply eq_pathover, refine !elim_merid ⬝ph _ ⬝hp !ap_constant⁻¹, exact square_of_eq !con.right_inv⁻¹ }
end
definition susp_functor_pconst [constructor] (X Y : Type*) :
susp_functor (pconst X Y) ~* pconst (susp X) (susp Y) :=
begin
fapply phomotopy.mk,
{ exact susp_functor_pconst_homotopy },
{ reflexivity }
end
definition susp_pfunctor [constructor] (X Y : Type*) : ppmap X Y →* ppmap (susp X) (susp Y) :=
pmap.mk susp_functor (eq_of_phomotopy !susp_functor_pconst)
definition susp_pelim [constructor] (X Y : Type*) : ppmap X (Ω Y) →* ppmap (susp X) Y :=
ppcompose_left (loop_susp_counit Y) ∘* susp_pfunctor X (Ω Y)
definition loop_susp_pintro [constructor] (X Y : Type*) : ppmap (susp X) Y →* ppmap X (Ω Y) :=
ppcompose_right (loop_susp_unit X) ∘* pap1 (susp X) Y
definition loop_susp_pintro_natural_left (f : X' →* X) :
psquare (loop_susp_pintro X Y) (loop_susp_pintro X' Y)
(ppcompose_right (susp_functor f)) (ppcompose_right f) :=
!pap1_natural_left ⬝h* ppcompose_right_psquare (loop_susp_unit_natural f)
definition loop_susp_pintro_natural_right (f : Y →* Y') :
psquare (loop_susp_pintro X Y) (loop_susp_pintro X Y')
(ppcompose_left f) (ppcompose_left (Ω→ f)) :=
!pap1_natural_right ⬝h* !ppcompose_left_ppcompose_right⁻¹*
definition is_equiv_loop_susp_pintro [constructor] (X Y : Type*) :
is_equiv (loop_susp_pintro X Y) :=
begin
fapply adjointify,
{ exact susp_pelim X Y },
{ intro g, apply eq_of_phomotopy, exact susp_adjoint_loop_right_inv g },
{ intro f, apply eq_of_phomotopy, exact susp_adjoint_loop_left_inv f }
end
definition susp_adjoint_loop [constructor] (X Y : Type*) : ppmap (susp X) Y ≃* ppmap X (Ω Y) :=
pequiv_of_pmap (loop_susp_pintro X Y) (is_equiv_loop_susp_pintro X Y)
definition susp_adjoint_loop_natural_right (f : Y →* Y') :
psquare (susp_adjoint_loop X Y) (susp_adjoint_loop X Y')
(ppcompose_left f) (ppcompose_left (Ω→ f)) :=
loop_susp_pintro_natural_right f
definition susp_adjoint_loop_natural_left (f : X' →* X) :
psquare (susp_adjoint_loop X Y) (susp_adjoint_loop X' Y)
(ppcompose_right (susp_functor f)) (ppcompose_right f) :=
loop_susp_pintro_natural_left f
definition ap1_susp_elim {A : Type*} {X : Type*} (p : A →* Ω X) :
Ω→(susp_elim p) ∘* loop_susp_unit A ~* p :=
susp_adjoint_loop_right_inv p
/- the underlying homotopies of susp_adjoint_loop_natural_* -/
definition susp_adjoint_loop_nat_right (f : susp X →* Y) (g : Y →* Z)
: susp_adjoint_loop X Z (g ∘* f) ~* ap1 g ∘* susp_adjoint_loop X Y f :=
begin
esimp [susp_adjoint_loop],
refine _ ⬝* !passoc,
apply pwhisker_right,
apply ap1_pcompose
end
definition susp_adjoint_loop_nat_left (f : Y →* Ω Z) (g : X →* Y)
: (susp_adjoint_loop X Z)⁻¹ᵉ (f ∘* g) ~* (susp_adjoint_loop Y Z)⁻¹ᵉ f ∘* susp_functor g :=
begin
esimp [susp_adjoint_loop],
refine _ ⬝* !passoc⁻¹*,
apply pwhisker_left,
apply susp_functor_pcompose
end
/- iterated suspension -/
definition iterate_susp (n : ) (A : Type*) : Type* := iterate (λX, susp X) n A
open is_conn trunc_index nat
definition iterate_susp_succ (n : ) (A : Type*) :
iterate_susp (succ n) A = susp (iterate_susp n A) :=
idp
definition is_conn_iterate_susp [instance] (n : ℕ₋₂) (m : ) (A : Type*)
[H : is_conn n A] : is_conn (n + m) (iterate_susp m A) :=
begin induction m with m IH, exact H, exact @is_conn_susp _ _ IH end
-- Separate cases for n = 0, which comes up often
definition is_conn_iterate_susp_zero [instance] (m : ) (A : Type*)
[H : is_conn 0 A] : is_conn m (iterate_susp m A) :=
begin induction m with m IH, exact H, exact @is_conn_susp _ _ IH end
definition iterate_susp_functor (n : ) {A B : Type*} (f : A →* B) :
iterate_susp n A →* iterate_susp n B :=
begin
induction n with n g,
{ exact f },
{ exact susp_functor g }
end
definition iterate_susp_succ_in (n : ) (A : Type*) :
iterate_susp (succ n) A ≃* iterate_susp n (susp A) :=
begin
induction n with n IH,
{ reflexivity},
{ exact susp_pequiv IH}
end
definition iterate_susp_adjoint_loopn [constructor] (X Y : Type*) (n : ) :
ppmap (iterate_susp n X) Y ≃* ppmap X (Ω[n] Y) :=
begin
revert X Y, induction n with n IH: intro X Y,
{ reflexivity },
{ refine !susp_adjoint_loop ⬝e* !IH ⬝e* _, apply ppmap_pequiv_ppmap_right,
symmetry, apply loopn_succ_in }
end
end susp