-
Notifications
You must be signed in to change notification settings - Fork 24
/
vankampen.hlean
378 lines (332 loc) · 14.4 KB
/
vankampen.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
/-
Copyright (c) 2016 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Floris van Doorn
-/
import hit.pushout hit.prop_trunc algebra.category.constructions.pushout
algebra.category.constructions.fundamental_groupoid algebra.category.functor.equivalence
open eq pushout category functor sum iso paths set_quotient is_trunc trunc pi quotient
is_equiv fiber equiv function
namespace pushout
section
universe variables u v w
parameters {S TL : Type.{u}} -- do we want to put these in different universe levels?
{BL : Type.{v}} {TR : Type.{w}} (k : S → TL) (f : TL → BL) (g : TL → TR)
[ksurj : is_surjective k]
definition pushout_of_sum [unfold 6] (x : BL + TR) : pushout f g :=
quotient.class_of _ x
include ksurj
local notation `F` := Π₁⇒ f
local notation `G` := Π₁⇒ g
local notation `C` := Groupoid_bpushout k F G
local notation `R` := bpushout_prehom_index k F G
local notation `Q` := bpushout_hom_rel_index k F G
local attribute is_trunc_equiv [instance]
open category.bpushout_prehom_index category.bpushout_hom_rel_index paths.paths_rel
protected definition code_equiv_pt (x : BL + TR) {y : TL} {s : S} (p : k s = y) :
@hom C _ x (sum.inl (f y)) ≃ @hom C _ x (sum.inr (g y)) :=
begin
fapply equiv_postcompose,
{ apply class_of,
refine [iE k F G (tap g (tr p)), DE k F G s, iD k F G (tap f (tr p⁻¹))]},
refine all_iso _
end
protected definition code_equiv_pt_constant (x : BL + TR) {y : TL} {s s' : S}
(p : k s = y) (p' : k s' = y) : code_equiv_pt x p = code_equiv_pt x p' :=
begin
apply equiv_eq, intro g,
apply ap (λx, x ∘ _),
induction p',
refine eq_of_rel (tr _) ⬝ (eq_of_rel (tr _))⁻¹,
{ exact [DE k _ _ s']},
{ refine rtrans (rel [_] (cohDE F G (tr p))) _,
refine rtrans (rcons _ (rel [] !DD)) _,
refine tr_rev (λx, paths_rel _ [_ , iD k F G (tr x)] _)
(!ap_con⁻¹ ⬝ ap02 f !con.left_inv) _,
exact rcons _ (rel [] !idD)},
refine rtrans (rel _ !idE) _,
exact rcons _ (rel [] !idD)
end
protected definition code_equiv (x : BL + TR) (y : TL) :
@hom C _ x (sum.inl (f y)) ≃ @hom C _ x (sum.inr (g y)) :=
begin
refine @prop_trunc.elim_set _ _ _ _ _ (ksurj y), { apply @is_trunc_equiv: apply is_set_hom},
{ intro v, cases v with s p,
exact code_equiv_pt x p},
intro v v', cases v with s p, cases v' with s' p',
exact code_equiv_pt_constant x p p'
end
theorem code_equiv_eq (x : BL + TR) (s : S) :
code_equiv x (k s) = @(equiv_postcompose (class_of [DE k F G s])) !all_iso :=
begin
apply equiv_eq, intro h,
-- induction h using set_quotient.rec_prop with l,
refine @set_quotient.rec_prop _ _ _ _ _ h, {intro l, apply is_trunc_eq, apply is_set_hom},
intro l,
have ksurj (k s) = tr (fiber.mk s idp), from !is_prop.elim,
refine ap (λz, to_fun (@prop_trunc.elim_set _ _ _ _ _ z) (class_of l)) this ⬝ _,
change class_of ([iE k F G (tr idp), DE k F G s, iD k F G (tr idp)] ++ l) =
class_of (DE k F G s :: l) :> @hom C _ _ _,
refine eq_of_rel (tr _) ⬝ (eq_of_rel (tr _)),
{ exact DE k F G s :: iD k F G (tr idp) :: l},
{ change paths_rel Q ([iE k F G (tr idp)] ++ (DE k F G s :: iD k F G (tr idp) :: l))
(nil ++ (DE k F G s :: iD k F G (tr idp) :: l)),
apply rel ([DE k F G s, iD k F G (tr idp)] ++ l),
apply idE},
{ apply rcons, rewrite [-nil_append l at {2}, -singleton_append], apply rel l, apply idD}
end
theorem to_fun_code_equiv (x : BL + TR) (s : S) (h : @hom C _ x (sum.inl (f (k s)))) :
(to_fun (code_equiv x (k s)) h) = @comp C _ _ _ _ (class_of [DE k F G s]) h :=
ap010 to_fun !code_equiv_eq h
protected definition code [unfold 10] (x : BL + TR) (y : pushout f g) : Type.{max u v w} :=
begin
refine quotient.elim_type _ _ y,
{ clear y, intro y, exact @hom C _ x y},
clear y, intro y z r, induction r with y,
exact code_equiv x y
end
/-
[iE (ap g p), DE s, iD (ap f p⁻¹)]
-->
[DE s', iD (ap f p), iD (ap f p⁻¹)]
-->
[DE s', iD (ap f p ∘ ap f p⁻¹)]
-->
[DE s']
<--
[iE 1, DE s', iD 1]
-/
definition is_set_code (x : BL + TR) (y : pushout f g) : is_set (code x y) :=
begin
induction y using pushout.rec_prop, apply is_set_hom, apply is_set_hom,
end
local attribute is_set_code [instance]
-- encode is easy
definition encode {x : BL + TR} {y : pushout f g} (p : trunc 0 (pushout_of_sum x = y)) :
code x y :=
begin
induction p with p,
exact transport (code x) p id
end
-- decode is harder
definition decode_reduction_rule [unfold 11] ⦃x x' : BL + TR⦄ (i : R x x') :
trunc 0 (pushout_of_sum x = pushout_of_sum x') :=
begin
induction i,
{ exact tap inl f_1},
{ exact tap inr g_1},
{ exact tr (glue (k s))},
{ exact tr (glue (k s))⁻¹},
end
definition decode_list ⦃x x' : BL + TR⦄ (l : paths R x x') :
trunc 0 (pushout_of_sum x = pushout_of_sum x') :=
realize (λa a', trunc 0 (pushout_of_sum a = pushout_of_sum a'))
decode_reduction_rule
(λa, tidp)
(λa₁ a₂ a₃, tconcat) l
definition decode_list_nil (x : BL + TR) : decode_list (@nil _ _ x) = tidp :=
idp
definition decode_list_cons ⦃x₁ x₂ x₃ : BL + TR⦄ (r : R x₂ x₃) (l : paths R x₁ x₂) :
decode_list (r :: l) = tconcat (decode_list l) (decode_reduction_rule r) :=
idp
definition decode_list_singleton ⦃x₁ x₂ : BL + TR⦄ (r : R x₁ x₂) :
decode_list [r] = decode_reduction_rule r :=
realize_singleton (λa b p, tidp_tcon p) r
definition decode_list_pair ⦃x₁ x₂ x₃ : BL + TR⦄ (r₂ : R x₂ x₃) (r₁ : R x₁ x₂) :
decode_list [r₂, r₁] = tconcat (decode_reduction_rule r₁) (decode_reduction_rule r₂) :=
realize_pair (λa b p, tidp_tcon p) r₂ r₁
definition decode_list_append ⦃x₁ x₂ x₃ : BL + TR⦄ (l₂ : paths R x₂ x₃)
(l₁ : paths R x₁ x₂) :
decode_list (l₂ ++ l₁) = tconcat (decode_list l₁) (decode_list l₂) :=
realize_append (λa b c d, tassoc) (λa b, tcon_tidp) l₂ l₁
theorem decode_list_rel ⦃x x' : BL + TR⦄ {l l' : paths R x x'} (H : Q l l') :
decode_list l = decode_list l' :=
begin
induction H,
{ rewrite [decode_list_pair, decode_list_singleton], exact !tap_tcon⁻¹},
{ rewrite [decode_list_pair, decode_list_singleton], exact !tap_tcon⁻¹},
{ rewrite [decode_list_pair, decode_list_nil], exact ap tr !con.right_inv},
{ rewrite [decode_list_pair, decode_list_nil], exact ap tr !con.left_inv},
{ apply decode_list_singleton},
{ apply decode_list_singleton},
{ rewrite [+decode_list_pair], induction h with p, apply ap tr, rewrite [+ap_compose'],
exact !ap_con_eq_con_ap⁻¹},
{ rewrite [+decode_list_pair], induction h with p, apply ap tr, rewrite [+ap_compose'],
apply ap_con_eq_con_ap}
end
definition decode_point [unfold 11] {x x' : BL + TR} (c : @hom C _ x x') :
trunc 0 (pushout_of_sum x = pushout_of_sum x') :=
begin
induction c with l,
{ exact decode_list l},
{ induction H with H, refine realize_eq _ _ _ H,
{ intros, apply tassoc},
{ intros, apply tcon_tidp},
{ clear H a a', intros, exact decode_list_rel a}}
end
theorem decode_coh (x : BL + TR) (y : TL) (p : trunc 0 (pushout_of_sum x = inl (f y))) :
p =[glue y] tconcat p (tr (glue y)) :=
begin
induction p with p,
apply trunc_pathover, apply eq_pathover_constant_left_id_right,
apply square_of_eq, exact !idp_con⁻¹
end
definition decode [unfold 7] {x : BL + TR} {y : pushout f g} (c : code x y) :
trunc 0 (pushout_of_sum x = y) :=
begin
induction y using quotient.rec with y,
{ exact decode_point c},
{ induction H with y, apply arrow_pathover_left, intro c,
revert c, apply @set_quotient.rec_prop, { intro z, apply is_trunc_pathover},
intro l,
refine _ ⬝op ap decode_point !quotient.elim_type_eq_of_rel⁻¹,
change pathover (λ a, trunc 0 (eq (pushout_of_sum x) a))
(decode_list l)
(eq_of_rel (pushout_rel f g) (pushout_rel.Rmk f g y))
(decode_point
(code_equiv x y (class_of l))),
note z := ksurj y, revert z,
apply @image.rec, { intro, apply is_trunc_pathover},
intro s p, induction p, rewrite to_fun_code_equiv,
refine _ ⬝op (decode_list_cons (DE k F G s) l)⁻¹,
esimp, generalize decode_list l,
apply @trunc.rec, { intro p, apply is_trunc_pathover},
intro p, apply trunc_pathover, apply eq_pathover_constant_left_id_right,
apply square_of_eq, exact !idp_con⁻¹}
end
-- report the failing of esimp in the commented-out proof below
-- definition decode [unfold 7] {x : BL + TR} {y : pushout f g} (c : code x y) :
-- trunc 0 (pushout_of_sum x = y) :=
-- begin
-- induction y using quotient.rec with y,
-- { exact decode_point c},
-- { induction H with y, apply arrow_pathover_left, intro c,
-- revert c, apply @set_quotient.rec_prop, { intro z, apply is_trunc_pathover},
-- intro l,
-- refine _ ⬝op ap decode_point !quotient.elim_type_eq_of_rel⁻¹,
-- --esimp,
-- change pathover (λ (a : pushout f g), trunc 0 (eq (pushout_of_sum x) a))
-- (decode_point (class_of l))
-- (glue y)
-- (decode_point (class_of ((pushout_prehom_index.lr F G id) :: l))),
-- esimp, rewrite [▸*, decode_list_cons, ▸*], generalize (decode_list l), clear l,
-- apply @trunc.rec, { intro z, apply is_trunc_pathover},
-- intro p, apply trunc_pathover, apply eq_pathover_constant_left_id_right,
-- apply square_of_eq, exact !idp_con⁻¹}
-- end
-- decode-encode is easy
protected theorem decode_encode {x : BL + TR} {y : pushout f g}
(p : trunc 0 (pushout_of_sum x = y)) : decode (encode p) = p :=
begin
induction p with p, induction p, reflexivity
end
definition is_surjective.rec {A B : Type} {f : A → B} (Hf : is_surjective f)
{P : B → Type} [Πb, is_prop (P b)] (H : Πa, P (f a)) (b : B) : P b :=
by induction Hf b; exact p ▸ H a
-- encode-decode is harder
definition code_comp [unfold 8] {x y : BL + TR} {z : pushout f g}
(c : code x (pushout_of_sum y)) (d : code y z) : code x z :=
begin
induction z using quotient.rec with z,
{ exact d ∘ c},
{ induction H with z,
apply arrow_pathover_left, intro d,
refine !pathover_tr ⬝op _,
refine !elim_type_eq_of_rel ⬝ _ ⬝ ap _ !elim_type_eq_of_rel⁻¹,
note q := ksurj z, revert q, apply @image.rec, { intro, apply is_trunc_eq, apply is_set_code},
intro s p, induction p,
refine !to_fun_code_equiv ⬝ _ ⬝ ap (λh, h ∘ c) !to_fun_code_equiv⁻¹, apply assoc}
end
theorem encode_tcon' {x y : BL + TR} {z : pushout f g}
(p : trunc 0 (pushout_of_sum x = pushout_of_sum y))
(q : trunc 0 (pushout_of_sum y = z)):
encode (tconcat p q) = code_comp (encode p) (encode q) :=
begin
induction q with q,
induction q,
refine ap encode !tcon_tidp ⬝ _,
symmetry, apply id_left
end
theorem encode_tcon {x y z : BL + TR}
(p : trunc 0 (pushout_of_sum x = pushout_of_sum y))
(q : trunc 0 (pushout_of_sum y = pushout_of_sum z)):
encode (tconcat p q) = encode q ∘ encode p :=
encode_tcon' p q
open category.bpushout_hom_rel_index
theorem encode_decode_singleton {x y : BL + TR} (r : R x y) :
encode (decode_reduction_rule r) = class_of [r] :=
begin
have is_prop (encode (decode_reduction_rule r) = class_of [r]), from !is_trunc_eq,
induction r,
{ induction f_1 with p, induction p, symmetry, apply eq_of_rel,
apply tr, apply paths_rel_of_Q, apply idD},
{ induction g_1 with p, induction p, symmetry, apply eq_of_rel,
apply tr, apply paths_rel_of_Q, apply idE},
{ refine !elim_type_eq_of_rel ⬝ _, apply to_fun_code_equiv},
{ refine !elim_type_eq_of_rel_inv' ⬝ _, apply ap010 to_inv !code_equiv_eq}
end
local attribute pushout [reducible]
protected theorem encode_decode {x : BL + TR} {y : pushout f g} (c : code x y) :
encode (decode c) = c :=
begin
induction y using quotient.rec_prop with y,
revert c, apply @set_quotient.rec_prop, { intro, apply is_trunc_eq}, intro l,
change encode (decode_list l) = class_of l,
induction l,
{ reflexivity},
{ rewrite [decode_list_cons, encode_tcon, encode_decode_singleton, v_0]}
end
definition pushout_teq_equiv [constructor] (x : BL + TR) (y : pushout f g) :
trunc 0 (pushout_of_sum x = y) ≃ code x y :=
equiv.MK encode
decode
encode_decode
decode_encode
definition vankampen [constructor] (x y : BL + TR) :
trunc 0 (pushout_of_sum x = pushout_of_sum y) ≃ @hom C _ x y :=
pushout_teq_equiv x (pushout_of_sum y)
--Groupoid_pushout k F G
definition decode_point_comp [unfold 8] {x₁ x₂ x₃ : BL + TR}
(c₂ : @hom C _ x₂ x₃) (c₁ : @hom C _ x₁ x₂) :
decode_point (c₂ ∘ c₁) = tconcat (decode_point c₁) (decode_point c₂) :=
begin
induction c₂ using set_quotient.rec_prop with l₂,
induction c₁ using set_quotient.rec_prop with l₁,
apply decode_list_append
end
definition vankampen_functor [constructor] : C ⇒ Π₁ (pushout f g) :=
begin
fconstructor,
{ exact pushout_of_sum},
{ intro x y c, exact decode_point c},
{ intro x, reflexivity},
{ intro x y z d c, apply decode_point_comp}
end
definition fully_faithful_vankampen_functor : fully_faithful vankampen_functor :=
begin
intro x x',
fapply adjointify,
{ apply encode},
{ intro p, apply decode_encode},
{ intro c, apply encode_decode}
end
definition essentially_surjective_vankampen_functor : essentially_surjective vankampen_functor :=
begin
intro z, induction z using quotient.rec_prop with x,
apply exists.intro x, reflexivity
end
definition is_weak_equivalence_vankampen_functor [constructor] :
is_weak_equivalence vankampen_functor :=
begin
constructor,
{ exact fully_faithful_vankampen_functor},
{ exact essentially_surjective_vankampen_functor}
end
definition fundamental_groupoid_bpushout [constructor] :
Groupoid_bpushout k (Π₁⇒ f) (Π₁⇒ g) ≃w Π₁ (pushout f g) :=
weak_equivalence.mk vankampen_functor is_weak_equivalence_vankampen_functor
end
definition fundamental_groupoid_pushout [constructor] {TL BL TR : Type}
(f : TL → BL) (g : TL → TR) : Groupoid_bpushout (@id TL) (Π₁⇒ f) (Π₁⇒ g) ≃w Π₁ (pushout f g) :=
fundamental_groupoid_bpushout (@id TL) f g
end pushout