-
Notifications
You must be signed in to change notification settings - Fork 24
/
susp.hlean
525 lines (433 loc) · 17.4 KB
/
susp.hlean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
/-
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