2015-04-07 01:01:08 +00:00
|
|
|
|
/-
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
Declaration of the circle
|
|
|
|
|
-/
|
|
|
|
|
|
2015-05-27 01:17:26 +00:00
|
|
|
|
import .sphere
|
|
|
|
|
import types.bool types.int.hott types.equiv
|
2015-11-16 20:30:28 +00:00
|
|
|
|
import algebra.homotopy_group algebra.hott
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
2015-06-17 19:58:58 +00:00
|
|
|
|
open eq susp bool sphere_index is_equiv equiv equiv.ops is_trunc pi
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
2015-05-07 20:35:14 +00:00
|
|
|
|
definition circle : Type₀ := sphere 1
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
|
|
|
|
namespace circle
|
2015-05-14 02:01:48 +00:00
|
|
|
|
notation `S¹` := circle
|
2015-04-07 01:01:08 +00:00
|
|
|
|
definition base1 : circle := !north
|
|
|
|
|
definition base2 : circle := !south
|
2015-04-28 02:05:59 +00:00
|
|
|
|
definition seg1 : base1 = base2 := merid !north
|
|
|
|
|
definition seg2 : base1 = base2 := merid !south
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
|
|
|
|
definition base : circle := base1
|
2015-05-22 08:35:38 +00:00
|
|
|
|
definition loop : base = base := seg2 ⬝ seg1⁻¹
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
|
|
|
|
definition rec2 {P : circle → Type} (Pb1 : P base1) (Pb2 : P base2)
|
2015-05-22 08:35:38 +00:00
|
|
|
|
(Ps1 : Pb1 =[seg1] Pb2) (Ps2 : Pb1 =[seg2] Pb2) (x : circle) : P x :=
|
2015-04-07 01:01:08 +00:00
|
|
|
|
begin
|
2015-05-21 04:16:23 +00:00
|
|
|
|
induction x with b,
|
2015-04-07 01:01:08 +00:00
|
|
|
|
{ exact Pb1},
|
|
|
|
|
{ exact Pb2},
|
2015-05-21 04:16:23 +00:00
|
|
|
|
{ esimp at *, induction b with y,
|
2015-04-28 02:05:59 +00:00
|
|
|
|
{ exact Ps1},
|
|
|
|
|
{ exact Ps2},
|
2015-05-21 04:16:23 +00:00
|
|
|
|
{ cases y}},
|
2015-04-07 01:01:08 +00:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
definition rec2_on [reducible] {P : circle → Type} (x : circle) (Pb1 : P base1) (Pb2 : P base2)
|
2015-05-22 08:35:38 +00:00
|
|
|
|
(Ps1 : Pb1 =[seg1] Pb2) (Ps2 : Pb1 =[seg2] Pb2) : P x :=
|
2015-04-07 01:01:08 +00:00
|
|
|
|
circle.rec2 Pb1 Pb2 Ps1 Ps2 x
|
|
|
|
|
|
2015-04-27 21:34:55 +00:00
|
|
|
|
theorem rec2_seg1 {P : circle → Type} (Pb1 : P base1) (Pb2 : P base2)
|
2015-05-22 08:35:38 +00:00
|
|
|
|
(Ps1 : Pb1 =[seg1] Pb2) (Ps2 : Pb1 =[seg2] Pb2)
|
|
|
|
|
: apdo (rec2 Pb1 Pb2 Ps1 Ps2) seg1 = Ps1 :=
|
2015-04-28 01:30:20 +00:00
|
|
|
|
!rec_merid
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
2015-04-27 21:34:55 +00:00
|
|
|
|
theorem rec2_seg2 {P : circle → Type} (Pb1 : P base1) (Pb2 : P base2)
|
2015-05-22 08:35:38 +00:00
|
|
|
|
(Ps1 : Pb1 =[seg1] Pb2) (Ps2 : Pb1 =[seg2] Pb2)
|
|
|
|
|
: apdo (rec2 Pb1 Pb2 Ps1 Ps2) seg2 = Ps2 :=
|
2015-04-28 02:05:59 +00:00
|
|
|
|
!rec_merid
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
2015-05-07 20:35:14 +00:00
|
|
|
|
definition elim2 {P : Type} (Pb1 Pb2 : P) (Ps1 Ps2 : Pb1 = Pb2) (x : circle) : P :=
|
2015-05-22 08:35:38 +00:00
|
|
|
|
rec2 Pb1 Pb2 (pathover_of_eq Ps1) (pathover_of_eq Ps2) x
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
|
|
|
|
definition elim2_on [reducible] {P : Type} (x : circle) (Pb1 Pb2 : P)
|
2015-04-28 02:05:59 +00:00
|
|
|
|
(Ps1 : Pb1 = Pb2) (Ps2 : Pb1 = Pb2) : P :=
|
2015-04-07 01:01:08 +00:00
|
|
|
|
elim2 Pb1 Pb2 Ps1 Ps2 x
|
|
|
|
|
|
2015-04-28 02:05:59 +00:00
|
|
|
|
theorem elim2_seg1 {P : Type} (Pb1 Pb2 : P) (Ps1 : Pb1 = Pb2) (Ps2 : Pb1 = Pb2)
|
2015-04-27 21:34:55 +00:00
|
|
|
|
: ap (elim2 Pb1 Pb2 Ps1 Ps2) seg1 = Ps1 :=
|
|
|
|
|
begin
|
2015-05-22 08:35:38 +00:00
|
|
|
|
apply eq_of_fn_eq_fn_inv !(pathover_constant seg1),
|
|
|
|
|
rewrite [▸*,-apdo_eq_pathover_of_eq_ap,↑elim2,rec2_seg1],
|
2015-04-27 21:34:55 +00:00
|
|
|
|
end
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
2015-04-28 02:05:59 +00:00
|
|
|
|
theorem elim2_seg2 {P : Type} (Pb1 Pb2 : P) (Ps1 : Pb1 = Pb2) (Ps2 : Pb1 = Pb2)
|
2015-04-27 21:34:55 +00:00
|
|
|
|
: ap (elim2 Pb1 Pb2 Ps1 Ps2) seg2 = Ps2 :=
|
|
|
|
|
begin
|
2015-05-22 08:35:38 +00:00
|
|
|
|
apply eq_of_fn_eq_fn_inv !(pathover_constant seg2),
|
|
|
|
|
rewrite [▸*,-apdo_eq_pathover_of_eq_ap,↑elim2,rec2_seg2],
|
2015-04-27 21:34:55 +00:00
|
|
|
|
end
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
2015-05-07 20:35:14 +00:00
|
|
|
|
definition elim2_type (Pb1 Pb2 : Type) (Ps1 Ps2 : Pb1 ≃ Pb2) (x : circle) : Type :=
|
|
|
|
|
elim2 Pb1 Pb2 (ua Ps1) (ua Ps2) x
|
|
|
|
|
|
|
|
|
|
definition elim2_type_on [reducible] (x : circle) (Pb1 Pb2 : Type) (Ps1 Ps2 : Pb1 ≃ Pb2)
|
|
|
|
|
: Type :=
|
|
|
|
|
elim2_type Pb1 Pb2 Ps1 Ps2 x
|
|
|
|
|
|
|
|
|
|
theorem elim2_type_seg1 (Pb1 Pb2 : Type) (Ps1 Ps2 : Pb1 ≃ Pb2)
|
|
|
|
|
: transport (elim2_type Pb1 Pb2 Ps1 Ps2) seg1 = Ps1 :=
|
|
|
|
|
by rewrite [tr_eq_cast_ap_fn,↑elim2_type,elim2_seg1];apply cast_ua_fn
|
|
|
|
|
|
|
|
|
|
theorem elim2_type_seg2 (Pb1 Pb2 : Type) (Ps1 Ps2 : Pb1 ≃ Pb2)
|
|
|
|
|
: transport (elim2_type Pb1 Pb2 Ps1 Ps2) seg2 = Ps2 :=
|
|
|
|
|
by rewrite [tr_eq_cast_ap_fn,↑elim2_type,elim2_seg2];apply cast_ua_fn
|
|
|
|
|
|
2015-05-22 08:35:38 +00:00
|
|
|
|
protected definition rec {P : circle → Type} (Pbase : P base) (Ploop : Pbase =[loop] Pbase)
|
2015-04-07 01:01:08 +00:00
|
|
|
|
(x : circle) : P x :=
|
|
|
|
|
begin
|
|
|
|
|
fapply (rec2_on x),
|
|
|
|
|
{ exact Pbase},
|
|
|
|
|
{ exact (transport P seg1 Pbase)},
|
2015-05-22 08:35:38 +00:00
|
|
|
|
{ apply pathover_tr},
|
|
|
|
|
{ apply pathover_tr_of_pathover, exact Ploop}
|
2015-04-07 01:01:08 +00:00
|
|
|
|
end
|
2015-04-27 21:34:55 +00:00
|
|
|
|
|
2015-04-07 01:01:08 +00:00
|
|
|
|
protected definition rec_on [reducible] {P : circle → Type} (x : circle) (Pbase : P base)
|
2015-05-22 08:35:38 +00:00
|
|
|
|
(Ploop : Pbase =[loop] Pbase) : P x :=
|
2015-05-19 05:35:18 +00:00
|
|
|
|
circle.rec Pbase Ploop x
|
2015-04-28 20:49:11 +00:00
|
|
|
|
|
|
|
|
|
theorem rec_loop_helper {A : Type} (P : A → Type)
|
2015-05-22 08:35:38 +00:00
|
|
|
|
{x y z : A} {p : x = y} {p' : z = y} {u : P x} {v : P z} (q : u =[p ⬝ p'⁻¹] v) :
|
|
|
|
|
pathover_tr_of_pathover q ⬝o !pathover_tr⁻¹ᵒ = q :=
|
|
|
|
|
by cases p'; cases q; exact idp
|
2015-04-28 20:49:11 +00:00
|
|
|
|
|
2015-04-29 00:48:39 +00:00
|
|
|
|
definition con_refl {A : Type} {x y : A} (p : x = y) : p ⬝ refl _ = p :=
|
|
|
|
|
eq.rec_on p idp
|
|
|
|
|
|
2015-05-22 08:35:38 +00:00
|
|
|
|
theorem rec_loop {P : circle → Type} (Pbase : P base) (Ploop : Pbase =[loop] Pbase) :
|
|
|
|
|
apdo (circle.rec Pbase Ploop) loop = Ploop :=
|
2015-04-28 20:49:11 +00:00
|
|
|
|
begin
|
2015-05-22 08:35:38 +00:00
|
|
|
|
rewrite [↑loop,apdo_con,↑circle.rec,↑circle.rec2_on,↑base,rec2_seg2,apdo_inv,rec2_seg1],
|
|
|
|
|
apply rec_loop_helper
|
2015-04-28 20:49:11 +00:00
|
|
|
|
end
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
|
|
|
|
protected definition elim {P : Type} (Pbase : P) (Ploop : Pbase = Pbase)
|
|
|
|
|
(x : circle) : P :=
|
2015-05-22 08:35:38 +00:00
|
|
|
|
circle.rec Pbase (pathover_of_eq Ploop) x
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
|
|
|
|
protected definition elim_on [reducible] {P : Type} (x : circle) (Pbase : P)
|
|
|
|
|
(Ploop : Pbase = Pbase) : P :=
|
2015-05-19 05:35:18 +00:00
|
|
|
|
circle.elim Pbase Ploop x
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
2015-04-27 21:34:55 +00:00
|
|
|
|
theorem elim_loop {P : Type} (Pbase : P) (Ploop : Pbase = Pbase) :
|
2015-05-19 05:35:18 +00:00
|
|
|
|
ap (circle.elim Pbase Ploop) loop = Ploop :=
|
2015-04-27 21:34:55 +00:00
|
|
|
|
begin
|
2015-05-22 08:35:38 +00:00
|
|
|
|
apply eq_of_fn_eq_fn_inv !(pathover_constant loop),
|
|
|
|
|
rewrite [▸*,-apdo_eq_pathover_of_eq_ap,↑circle.elim,rec_loop],
|
2015-04-27 21:34:55 +00:00
|
|
|
|
end
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
2015-04-19 21:56:24 +00:00
|
|
|
|
protected definition elim_type (Pbase : Type) (Ploop : Pbase ≃ Pbase)
|
|
|
|
|
(x : circle) : Type :=
|
2015-05-19 05:35:18 +00:00
|
|
|
|
circle.elim Pbase (ua Ploop) x
|
2015-04-19 21:56:24 +00:00
|
|
|
|
|
|
|
|
|
protected definition elim_type_on [reducible] (x : circle) (Pbase : Type)
|
|
|
|
|
(Ploop : Pbase ≃ Pbase) : Type :=
|
2015-05-19 05:35:18 +00:00
|
|
|
|
circle.elim_type Pbase Ploop x
|
2015-04-19 21:56:24 +00:00
|
|
|
|
|
2015-04-27 21:34:55 +00:00
|
|
|
|
theorem elim_type_loop (Pbase : Type) (Ploop : Pbase ≃ Pbase) :
|
2015-05-19 05:35:18 +00:00
|
|
|
|
transport (circle.elim_type Pbase Ploop) loop = Ploop :=
|
|
|
|
|
by rewrite [tr_eq_cast_ap_fn,↑circle.elim_type,circle.elim_loop];apply cast_ua_fn
|
2015-04-07 01:01:08 +00:00
|
|
|
|
|
2015-05-07 02:48:11 +00:00
|
|
|
|
theorem elim_type_loop_inv (Pbase : Type) (Ploop : Pbase ≃ Pbase) :
|
2015-05-19 05:35:18 +00:00
|
|
|
|
transport (circle.elim_type Pbase Ploop) loop⁻¹ = to_inv Ploop :=
|
2015-08-07 17:23:00 +00:00
|
|
|
|
by rewrite [tr_inv_fn]; apply inv_eq_inv; apply elim_type_loop
|
2015-05-07 20:35:14 +00:00
|
|
|
|
end circle
|
|
|
|
|
|
2015-05-21 03:37:43 +00:00
|
|
|
|
attribute circle.base1 circle.base2 circle.base [constructor]
|
2015-07-07 23:37:06 +00:00
|
|
|
|
attribute circle.rec2 circle.elim2 [unfold 6] [recursor 6]
|
|
|
|
|
attribute circle.elim2_type [unfold 5]
|
|
|
|
|
attribute circle.rec2_on circle.elim2_on [unfold 2]
|
|
|
|
|
attribute circle.elim2_type [unfold 1]
|
2015-07-29 12:17:16 +00:00
|
|
|
|
attribute circle.rec circle.elim [unfold 4] [recursor 4]
|
2015-07-07 23:37:06 +00:00
|
|
|
|
attribute circle.elim_type [unfold 3]
|
|
|
|
|
attribute circle.rec_on circle.elim_on [unfold 2]
|
|
|
|
|
attribute circle.elim_type_on [unfold 1]
|
2015-05-07 02:48:11 +00:00
|
|
|
|
|
2015-05-07 20:35:14 +00:00
|
|
|
|
namespace circle
|
2015-05-14 02:01:48 +00:00
|
|
|
|
definition pointed_circle [instance] [constructor] : pointed circle :=
|
|
|
|
|
pointed.mk base
|
|
|
|
|
|
2015-11-16 20:30:28 +00:00
|
|
|
|
definition Circle [constructor] : Type* := pointed.mk' circle
|
|
|
|
|
notation `S¹.` := Circle
|
|
|
|
|
|
2015-05-01 00:45:31 +00:00
|
|
|
|
definition loop_neq_idp : loop ≠ idp :=
|
|
|
|
|
assume H : loop = idp,
|
2015-05-22 08:35:38 +00:00
|
|
|
|
have H2 : Π{A : Type₁} {a : A} {p : a = a}, p = idp,
|
2015-05-01 00:45:31 +00:00
|
|
|
|
from λA a p, calc
|
|
|
|
|
p = ap (circle.elim a p) loop : elim_loop
|
|
|
|
|
... = ap (circle.elim a p) (refl base) : by rewrite H,
|
2015-10-16 19:15:44 +00:00
|
|
|
|
eq_bnot_ne_idp H2
|
2015-05-01 00:45:31 +00:00
|
|
|
|
|
|
|
|
|
definition nonidp (x : circle) : x = x :=
|
2015-05-22 08:35:38 +00:00
|
|
|
|
begin
|
|
|
|
|
induction x,
|
|
|
|
|
{ exact loop},
|
2015-05-27 01:17:26 +00:00
|
|
|
|
{ apply concato_eq, apply pathover_eq_lr, rewrite [con.left_inv,idp_con]}
|
2015-05-22 08:35:38 +00:00
|
|
|
|
end
|
2015-05-01 00:45:31 +00:00
|
|
|
|
|
|
|
|
|
definition nonidp_neq_idp : nonidp ≠ (λx, idp) :=
|
|
|
|
|
assume H : nonidp = λx, idp,
|
|
|
|
|
have H2 : loop = idp, from apd10 H base,
|
|
|
|
|
absurd H2 loop_neq_idp
|
|
|
|
|
|
2015-05-07 02:48:11 +00:00
|
|
|
|
open int
|
|
|
|
|
|
2015-11-18 20:08:06 +00:00
|
|
|
|
protected definition code [unfold 1] (x : circle) : Type₀ :=
|
2015-05-07 02:48:11 +00:00
|
|
|
|
circle.elim_type_on x ℤ equiv_succ
|
|
|
|
|
|
2015-05-19 05:35:18 +00:00
|
|
|
|
definition transport_code_loop (a : ℤ) : transport circle.code loop a = succ a :=
|
2015-05-07 02:48:11 +00:00
|
|
|
|
ap10 !elim_type_loop a
|
|
|
|
|
|
2015-11-18 23:08:38 +00:00
|
|
|
|
definition transport_code_loop_inv (a : ℤ) : transport circle.code loop⁻¹ a = pred a :=
|
2015-05-07 02:48:11 +00:00
|
|
|
|
ap10 !elim_type_loop_inv a
|
|
|
|
|
|
2015-11-18 20:08:06 +00:00
|
|
|
|
protected definition encode [unfold 2] {x : circle} (p : base = x) : circle.code x :=
|
|
|
|
|
transport circle.code p (of_num 0)
|
2015-05-07 02:48:11 +00:00
|
|
|
|
|
2015-11-18 20:08:06 +00:00
|
|
|
|
protected definition decode [unfold 1] {x : circle} : circle.code x → base = x :=
|
2015-05-14 02:01:48 +00:00
|
|
|
|
begin
|
2015-05-21 04:16:23 +00:00
|
|
|
|
induction x,
|
2015-05-14 02:01:48 +00:00
|
|
|
|
{ exact power loop},
|
2015-05-27 01:17:26 +00:00
|
|
|
|
{ apply arrow_pathover_left, intro b, apply concato_eq, apply pathover_eq_r,
|
2015-05-27 23:38:31 +00:00
|
|
|
|
rewrite [power_con,transport_code_loop]}
|
2015-05-14 02:01:48 +00:00
|
|
|
|
end
|
|
|
|
|
|
2015-07-29 14:08:28 +00:00
|
|
|
|
definition circle_eq_equiv [constructor] (x : circle) : (base = x) ≃ circle.code x :=
|
2015-05-07 02:48:11 +00:00
|
|
|
|
begin
|
|
|
|
|
fapply equiv.MK,
|
2015-05-19 05:35:18 +00:00
|
|
|
|
{ exact circle.encode},
|
|
|
|
|
{ exact circle.decode},
|
2015-11-18 20:08:06 +00:00
|
|
|
|
{ exact abstract [irreducible] begin
|
|
|
|
|
induction x,
|
|
|
|
|
{ intro a, esimp, apply rec_nat_on a,
|
|
|
|
|
{ exact idp},
|
|
|
|
|
{ intros n p, rewrite [↑circle.encode, -power_con, con_tr, transport_code_loop],
|
|
|
|
|
exact ap succ p},
|
|
|
|
|
{ intros n p, rewrite [↑circle.encode, nat_succ_eq_int_succ, neg_succ, -power_con_inv,
|
|
|
|
|
@con_tr _ circle.code, transport_code_loop_inv, ↑[circle.encode] at p, p, -neg_succ] }},
|
|
|
|
|
{ apply pathover_of_tr_eq, apply eq_of_homotopy, intro a, apply @is_hset.elim,
|
|
|
|
|
esimp, exact _} end end},
|
2015-05-07 02:48:11 +00:00
|
|
|
|
{ intro p, cases p, exact idp},
|
|
|
|
|
end
|
|
|
|
|
|
2015-07-29 14:08:28 +00:00
|
|
|
|
definition base_eq_base_equiv [constructor] : base = base ≃ ℤ :=
|
2015-05-07 02:48:11 +00:00
|
|
|
|
circle_eq_equiv base
|
|
|
|
|
|
2015-11-18 23:08:38 +00:00
|
|
|
|
definition decode_add (a b : ℤ) : circle.decode a ⬝ circle.decode b = circle.decode (a + b) :=
|
2015-05-14 02:01:48 +00:00
|
|
|
|
!power_con_power
|
|
|
|
|
|
2015-05-19 05:35:18 +00:00
|
|
|
|
definition encode_con (p q : base = base) : circle.encode (p ⬝ q) = circle.encode p + circle.encode q :=
|
2015-05-14 02:01:48 +00:00
|
|
|
|
preserve_binary_of_inv_preserve base_eq_base_equiv concat add decode_add p q
|
|
|
|
|
|
|
|
|
|
--the carrier of π₁(S¹) is the set-truncation of base = base.
|
2015-11-18 23:08:38 +00:00
|
|
|
|
open algebra trunc equiv.ops
|
2015-11-16 20:30:28 +00:00
|
|
|
|
definition fg_carrier_equiv_int : π[1](S¹.) ≃ ℤ :=
|
2015-08-07 17:23:00 +00:00
|
|
|
|
trunc_equiv_trunc 0 base_eq_base_equiv ⬝e !trunc_equiv
|
2015-05-14 02:01:48 +00:00
|
|
|
|
|
2015-07-29 14:08:28 +00:00
|
|
|
|
definition con_comm_base (p q : base = base) : p ⬝ q = q ⬝ p :=
|
|
|
|
|
eq_of_fn_eq_fn base_eq_base_equiv (by esimp;rewrite [+encode_con,add.comm])
|
|
|
|
|
|
2015-11-16 20:30:28 +00:00
|
|
|
|
definition fundamental_group_of_circle : π₁(S¹.) = group_integers :=
|
2015-05-14 02:01:48 +00:00
|
|
|
|
begin
|
|
|
|
|
apply (Group_eq fg_carrier_equiv_int),
|
|
|
|
|
intros g h,
|
2015-05-27 02:33:27 +00:00
|
|
|
|
induction g with g', induction h with h',
|
2015-05-14 02:01:48 +00:00
|
|
|
|
apply encode_con,
|
|
|
|
|
end
|
2015-05-07 02:48:11 +00:00
|
|
|
|
|
2015-11-18 23:08:38 +00:00
|
|
|
|
open nat
|
|
|
|
|
definition homotopy_group_of_circle (n : ℕ) : πG[n+1 +1] S¹. = G0 :=
|
|
|
|
|
begin
|
|
|
|
|
refine @trivial_homotopy_of_is_hset_loop_space S¹. 1 n _,
|
|
|
|
|
apply is_trunc_equiv_closed_rev, apply base_eq_base_equiv
|
|
|
|
|
end
|
|
|
|
|
|
2015-07-29 14:08:28 +00:00
|
|
|
|
definition eq_equiv_Z (x : S¹) : x = x ≃ ℤ :=
|
|
|
|
|
begin
|
|
|
|
|
induction x,
|
|
|
|
|
{ apply base_eq_base_equiv},
|
|
|
|
|
{ apply equiv_pathover, intro p p' q, apply pathover_of_eq,
|
|
|
|
|
let H := eq_of_square (square_of_pathover q),
|
|
|
|
|
rewrite con_comm_base at H,
|
|
|
|
|
let H' := cancel_left H,
|
|
|
|
|
induction H', reflexivity}
|
|
|
|
|
end
|
|
|
|
|
|
2015-04-07 01:01:08 +00:00
|
|
|
|
end circle
|