feat(library/hott): begin porting Coq HoTT
This commit is contained in:
parent
0ea2d287e1
commit
218c9dfc81
2 changed files with 1191 additions and 169 deletions
|
@ -1,243 +1,343 @@
|
|||
-- Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
||||
-- Released under Apache 2.0 license as described in the file LICENSE.
|
||||
-- Author: Leonardo de Moura
|
||||
-- Author: Leonardo de Moura, Jeremy Avigad
|
||||
-- Ported from Coq HoTT
|
||||
|
||||
notation `assume` binders `,` r:(scoped f, f) := r
|
||||
notation `take` binders `,` r:(scoped f, f) := r
|
||||
|
||||
abbreviation id {A : Type} (a : A) := a
|
||||
abbreviation compose {A : Type} {B : Type} {C : Type} (g : B → C) (f : A → B) := λ x, g (f x)
|
||||
infixl `∘`:60 := compose
|
||||
|
||||
inductive path {A : Type} (a : A) : A → Type :=
|
||||
| refl : path a a
|
||||
|
||||
infix `=`:50 := path
|
||||
-- -- Equivalences
|
||||
-- -- ------------
|
||||
|
||||
definition transport {A : Type} {a b : A} {P : A → Type} (H1 : a = b) (H2 : P a) : P b
|
||||
:= path_rec H2 H1
|
||||
-- abbreviation Sect {A B : Type} (s : A → B) (r : B → A) := Πx : A, r (s x) ≈ x
|
||||
|
||||
namespace logic
|
||||
notation p `*(`:75 u `)` := transport p u
|
||||
end logic
|
||||
using logic
|
||||
-- -- TODO: need better means of declaring structures
|
||||
-- -- TODO: note that Coq allows projections to be declared to be coercions on the fly
|
||||
-- -- TODO: also think about namespaces: what should be in / out?
|
||||
-- -- TODO: can we omit ': Type'?
|
||||
|
||||
definition symm {A : Type} {a b : A} (p : a = b) : b = a
|
||||
:= p*(refl a)
|
||||
-- -- Structure IsEquiv
|
||||
|
||||
definition trans {A : Type} {a b c : A} (p1 : a = b) (p2 : b = c) : a = c
|
||||
:= p2*(p1)
|
||||
-- inductive IsEquiv {A B : Type} (f : A → B) : Type :=
|
||||
-- | IsEquiv_mk : Π
|
||||
-- (equiv_inv : B → A)
|
||||
-- (eisretr : Sect equiv_inv f)
|
||||
-- (eissect : Sect f equiv_inv)
|
||||
-- (eisadj : Πx, eisretr (f x) ≈ ap f (eissect x)),
|
||||
-- IsEquiv f
|
||||
|
||||
calc_subst transport
|
||||
calc_refl refl
|
||||
calc_trans trans
|
||||
-- definition equiv_inv {A B : Type} {f : A → B} (H : IsEquiv f) : B → A :=
|
||||
-- IsEquiv_rec (λequiv_inv eisretr eissect eisadj, equiv_inv) H
|
||||
|
||||
namespace logic
|
||||
postfix `⁻¹`:100 := symm
|
||||
infixr `⬝`:75 := trans
|
||||
end logic
|
||||
using logic
|
||||
-- -- TODO: note: does not type check without giving the type
|
||||
-- definition eisretr {A B : Type} {f : A → B} (H : IsEquiv f) : Sect (equiv_inv H) f :=
|
||||
-- IsEquiv_rec (λequiv_inv eisretr eissect eisadj, eisretr) H
|
||||
|
||||
theorem trans_refl_right {A : Type} {x y : A} (p : x = y) : p = p ⬝ (refl y)
|
||||
:= refl p
|
||||
-- definition eissect {A B : Type} {f : A → B} (H : IsEquiv f) : Sect f (equiv_inv H) :=
|
||||
-- IsEquiv_rec (λequiv_inv eisretr eissect eisadj, eissect) H
|
||||
|
||||
theorem trans_refl_left {A : Type} {x y : A} (p : x = y) : p = (refl x) ⬝ p
|
||||
:= path_rec (trans_refl_right (refl x)) p
|
||||
-- definition eisadj {A B : Type} {f : A → B} (H : IsEquiv f) :
|
||||
-- Πx, eisretr H (f x) ≈ ap f (eissect H x) :=
|
||||
-- IsEquiv_rec (λequiv_inv eisretr eissect eisadj, eisadj) H
|
||||
|
||||
theorem refl_symm {A : Type} (x : A) : (refl x)⁻¹ = (refl x)
|
||||
:= refl (refl x)
|
||||
-- -- Structure Equiv
|
||||
|
||||
theorem refl_trans {A : Type} (x : A) : (refl x) ⬝ (refl x) = (refl x)
|
||||
:= refl (refl x)
|
||||
-- inductive Equiv (A B : Type) : Type :=
|
||||
-- | Equiv_mk : Π
|
||||
-- (equiv_fun : A → B)
|
||||
-- (equiv_isequiv : IsEquiv equiv_fun),
|
||||
-- Equiv A B
|
||||
|
||||
theorem trans_symm {A : Type} {x y : A} (p : x = y) : p ⬝ p⁻¹ = refl x
|
||||
:= have q : (refl x) ⬝ (refl x)⁻¹ = refl x, from
|
||||
((refl_symm x)⁻¹)*(refl_trans x),
|
||||
path_rec q p
|
||||
-- definition equiv_fun {A B : Type} (e : Equiv A B) : A → B :=
|
||||
-- Equiv_rec (λequiv_fun equiv_isequiv, equiv_fun) e
|
||||
|
||||
theorem symm_trans {A : Type} {x y : A} (p : x = y) : p⁻¹ ⬝ p = refl y
|
||||
:= have q : (refl x)⁻¹ ⬝ (refl x) = refl x, from
|
||||
((refl_symm x)⁻¹)*(refl_trans x),
|
||||
path_rec q p
|
||||
-- -- TODO: use a type class instead?
|
||||
-- coercion equiv_fun : Equiv
|
||||
|
||||
theorem symm_symm {A : Type} {x y : A} (p : x = y) : (p⁻¹)⁻¹ = p
|
||||
:= have q : ((refl x)⁻¹)⁻¹ = refl x, from
|
||||
refl (refl x),
|
||||
path_rec q p
|
||||
-- definition equiv_isequiv [coercion] {A B : Type} (e : Equiv A B) : IsEquiv (equiv_fun e) :=
|
||||
-- Equiv_rec (λequiv_fun equiv_isequiv, equiv_isequiv) e
|
||||
|
||||
theorem trans_assoc {A : Type} {x y z w : A} (p : x = y) (q : y = z) (r : z = w) : p ⬝ (q ⬝ r) = (p ⬝ q) ⬝ r
|
||||
:= have e1 : (p ⬝ q) ⬝ (refl z) = p ⬝ q, from
|
||||
(trans_refl_right (p ⬝ q))⁻¹,
|
||||
have e2 : q ⬝ (refl z) = q, from
|
||||
(trans_refl_right q)⁻¹,
|
||||
have e3 : p ⬝ (q ⬝ (refl z)) = p ⬝ q, from
|
||||
e2*(refl (p ⬝ (q ⬝ (refl z)))),
|
||||
path_rec (e3 ⬝ e1⁻¹) r
|
||||
-- -- coercion equiv_isequiv
|
||||
|
||||
definition ap {A : Type} {B : Type} (f : A → B) {a b : A} (p : a = b) : f a = f b
|
||||
:= p*(refl (f a))
|
||||
-- -- TODO: better symbol
|
||||
-- infix `<~>`:25 := Equiv
|
||||
-- notation e `⁻¹`:75 := equiv_inv e
|
||||
|
||||
theorem ap_refl {A : Type} {B : Type} (f : A → B) (a : A) : ap f (refl a) = refl (f a)
|
||||
:= refl (refl (f a))
|
||||
|
||||
section
|
||||
parameters {A : Type} {B : Type} {C : Type}
|
||||
parameters (f : A → B) (g : B → C)
|
||||
parameters (x y z : A) (p : x = y) (q : y = z)
|
||||
-- -- Truncation levels
|
||||
-- -- -----------------
|
||||
|
||||
theorem ap_trans_dist : ap f (p ⬝ q) = (ap f p) ⬝ (ap f q)
|
||||
:= have e1 : ap f (p ⬝ refl y) = (ap f p) ⬝ (ap f (refl y)), from refl _,
|
||||
path_rec e1 q
|
||||
-- inductive Contr (A : Type) : Type :=
|
||||
-- | Contr_mk : Π
|
||||
-- (center : A)
|
||||
-- (contr : Πy : A, center ≈ y),
|
||||
-- Contr A
|
||||
|
||||
theorem ap_inv_dist : ap f (p⁻¹) = (ap f p)⁻¹
|
||||
:= have e1 : ap f ((refl x)⁻¹) = (ap f (refl x))⁻¹, from refl _,
|
||||
path_rec e1 p
|
||||
-- definition center {A : Type} (C : Contr A) : A := Contr_rec (λcenter contr, center) C
|
||||
|
||||
theorem ap_compose : ap g (ap f p) = ap (g∘f) p
|
||||
:= have e1 : ap g (ap f (refl x)) = ap (g∘f) (refl x), from refl _,
|
||||
path_rec e1 p
|
||||
-- definition contr {A : Type} (C : Contr A) : Πy : A, center C ≈ y :=
|
||||
-- Contr_rec (λcenter contr, contr) C
|
||||
|
||||
theorem ap_id : ap id p = p
|
||||
:= have e1 : ap id (refl x) = (refl x), from refl (refl x),
|
||||
path_rec e1 p
|
||||
end
|
||||
-- inductive trunc_index : Type :=
|
||||
-- | minus_two : trunc_index
|
||||
-- | trunc_S : trunc_index → trunc_index
|
||||
|
||||
section
|
||||
parameters {A : Type} {B : A → Type} (f : Π x, B x)
|
||||
definition D [private] (x y : A) (p : x = y) := p*(f x) = f y
|
||||
definition d [private] (x : A) : D x x (refl x)
|
||||
:= refl (f x)
|
||||
-- -- TODO: add coercions to / from nat
|
||||
|
||||
theorem apd {a b : A} (p : a = b) : p*(f a) = f b
|
||||
:= path_rec (d a) p
|
||||
end
|
||||
-- -- TODO: note in the Coq version, there is an internal version
|
||||
-- definition IsTrunc (n : trunc_index) : Type → Type :=
|
||||
-- trunc_index_rec (λA, Contr A) (λn trunc_n A, (Π(x y : A), trunc_n (x ≈ y))) n
|
||||
|
||||
-- -- TODO: in the Coq version, this is notation
|
||||
-- abbreviation minus_one := trunc_S minus_two
|
||||
-- abbreviation IsHProp := IsTrunc minus_one
|
||||
-- abbreviation IsHSet := IsTrunc (trunc_S minus_one)
|
||||
|
||||
abbreviation homotopy {A : Type} {P : A → Type} (f g : Π x, P x)
|
||||
:= Π x, f x = g x
|
||||
-- prefix `!`:75 := center
|
||||
|
||||
namespace logic
|
||||
infix `∼`:50 := homotopy
|
||||
end logic
|
||||
using logic
|
||||
|
||||
notation `assume` binders `,` r:(scoped f, f) := r
|
||||
notation `take` binders `,` r:(scoped f, f) := r
|
||||
-- -- Funext
|
||||
-- -- ------
|
||||
|
||||
section
|
||||
parameters {A : Type} {B : Type}
|
||||
-- -- TODO: move this to an "axioms" folder
|
||||
-- -- TODO: take a look at the Coq tricks
|
||||
-- axiom funext {A : Type} {P : A → Type} (f g : Π x : A, P x) : IsEquiv (@apD10 A P f g)
|
||||
|
||||
theorem hom_refl (f : A → B) : f ∼ f
|
||||
:= take x, refl (f x)
|
||||
-- definition path_forall {A : Type} {P : A → Type} (f g : Π x : A, P x) : f ∼ g → f ≈ g :=
|
||||
-- (funext f g)⁻¹
|
||||
|
||||
theorem hom_symm {f g : A → B} : f ∼ g → g ∼ f
|
||||
:= assume h, take x, (h x)⁻¹
|
||||
-- definition path_forall2 {A B : Type} {P : A → B → Type} (f g : Π x y, P x y) :
|
||||
-- (Πx y, f x y ≈ g x y) → f ≈ g :=
|
||||
-- λE, path_forall f g (λx, path_forall (f x) (g x) (E x))
|
||||
|
||||
theorem hom_trans {f g h : A → B} : f ∼ g → g ∼ h → f ∼ h
|
||||
:= assume h1 h2, take x, (h1 x) ⬝ (h2 x)
|
||||
|
||||
theorem hom_fun {f g : A → B} {x y : A} (H : f ∼ g) (p : x = y) : (H x) ⬝ (ap g p) = (ap f p) ⬝ (H y)
|
||||
:= have e1 : (H x) ⬝ (refl (g x)) = (refl (f x)) ⬝ (H x), from
|
||||
calc (H x) ⬝ (refl (g x)) = H x : (trans_refl_right (H x))⁻¹
|
||||
... = (refl (f x)) ⬝ (H x) : trans_refl_left (H x),
|
||||
have e2 : (H x) ⬝ (ap g (refl x)) = (ap f (refl x)) ⬝ (H x), from
|
||||
calc (H x) ⬝ (ap g (refl x)) = (H x) ⬝ (refl (g x)) : {ap_refl g x}
|
||||
... = (refl (f x)) ⬝ (H x) : e1
|
||||
... = (ap f (refl x)) ⬝ (H x) : {symm (ap_refl f x)},
|
||||
path_rec e2 p
|
||||
-- -- Empty type
|
||||
-- -- ----------
|
||||
|
||||
-- inductive empty : Type
|
||||
|
||||
end
|
||||
-- theorem empty_elim (A : Type) (H : empty) : A :=
|
||||
-- empty_rec (λ e, A) H
|
||||
|
||||
definition loop_space (A : Type) (a : A) := a = a
|
||||
notation `Ω` `(` A `,` a `)` := loop_space A a
|
||||
|
||||
definition loop2d_space (A : Type) (a : A) := (refl a) = (refl a)
|
||||
notation `Ω²` `(` A `,` a `)` := loop2d_space A a
|
||||
|
||||
inductive empty : Type
|
||||
|
||||
theorem empty_elim (c : Type) (H : empty) : c
|
||||
:= empty_rec (λ e, c) H
|
||||
-- inductive true : Prop :=
|
||||
-- | trivial : true
|
||||
|
||||
definition not (A : Type) := A → empty
|
||||
prefix `¬`:40 := not
|
||||
-- abbreviation not (a : Prop) := a → false
|
||||
-- prefix `¬`:40 := not
|
||||
|
||||
theorem not_intro {a : Type} (H : a → empty) : ¬ a
|
||||
:= H
|
||||
|
||||
theorem not_elim {a : Type} (H1 : ¬ a) (H2 : a) : empty
|
||||
:= H1 H2
|
||||
|
||||
theorem absurd {a : Type} (H1 : a) (H2 : ¬ a) : empty
|
||||
:= H2 H1
|
||||
-- theorem trans_refl_right {A : Type} {x y : A} (p : x = y) : p = p ⬝ (refl y)
|
||||
-- := refl p
|
||||
|
||||
theorem mt {a b : Type} (H1 : a → b) (H2 : ¬ b) : ¬ a
|
||||
:= assume Ha : a, absurd (H1 Ha) H2
|
||||
-- theorem trans_refl_left {A : Type} {x y : A} (p : x = y) : p = (refl x) ⬝ p
|
||||
-- := path_rec (trans_refl_right (refl x)) p
|
||||
|
||||
theorem contrapos {a b : Type} (H : a → b) : ¬ b → ¬ a
|
||||
:= assume Hnb : ¬ b, mt H Hnb
|
||||
-- theorem refl_symm {A : Type} (x : A) : (refl x)⁻¹ = (refl x)
|
||||
-- := refl (refl x)
|
||||
|
||||
theorem absurd_elim {a : Type} (b : Type) (H1 : a) (H2 : ¬ a) : b
|
||||
:= empty_elim b (absurd H1 H2)
|
||||
-- theorem refl_trans {A : Type} (x : A) : (refl x) ⬝ (refl x) = (refl x)
|
||||
-- := refl (refl x)
|
||||
|
||||
inductive unit : Type :=
|
||||
| star : unit
|
||||
-- theorem trans_symm {A : Type} {x y : A} (p : x = y) : p ⬝ p⁻¹ = refl x
|
||||
-- := have q : (refl x) ⬝ (refl x)⁻¹ = refl x, from
|
||||
-- ((refl_symm x)⁻¹)*(refl_trans x),
|
||||
-- path_rec q p
|
||||
|
||||
notation `⋆`:max := star
|
||||
-- theorem symm_trans {A : Type} {x y : A} (p : x = y) : p⁻¹ ⬝ p = refl y
|
||||
-- := have q : (refl x)⁻¹ ⬝ (refl x) = refl x, from
|
||||
-- ((refl_symm x)⁻¹)*(refl_trans x),
|
||||
-- path_rec q p
|
||||
|
||||
theorem absurd_not_unit (H : ¬ unit) : empty
|
||||
:= absurd star H
|
||||
-- theorem symm_symm {A : Type} {x y : A} (p : x = y) : (p⁻¹)⁻¹ = p
|
||||
-- := have q : ((refl x)⁻¹)⁻¹ = refl x, from
|
||||
-- refl (refl x),
|
||||
-- path_rec q p
|
||||
|
||||
theorem not_empty_trivial : ¬ empty
|
||||
:= assume H : empty, H
|
||||
-- theorem trans_assoc {A : Type} {x y z w : A} (p : x = y) (q : y = z) (r : z = w) : p ⬝ (q ⬝ r) = (p ⬝ q) ⬝ r
|
||||
-- := have e1 : (p ⬝ q) ⬝ (refl z) = p ⬝ q, from
|
||||
-- (trans_refl_right (p ⬝ q))⁻¹,
|
||||
-- have e2 : q ⬝ (refl z) = q, from
|
||||
-- (trans_refl_right q)⁻¹,
|
||||
-- have e3 : p ⬝ (q ⬝ (refl z)) = p ⬝ q, from
|
||||
-- e2*(refl (p ⬝ (q ⬝ (refl z)))),
|
||||
-- path_rec (e3 ⬝ e1⁻¹) r
|
||||
|
||||
theorem upun (x : unit) : x = ⋆
|
||||
:= unit_rec (refl ⋆) x
|
||||
-- definition ap {A : Type} {B : Type} (f : A → B) {a b : A} (p : a = b) : f a = f b
|
||||
-- := p*(refl (f a))
|
||||
|
||||
inductive product (A : Type) (B : Type) : Type :=
|
||||
| pair : A → B → product A B
|
||||
-- theorem ap_refl {A : Type} {B : Type} (f : A → B) (a : A) : ap f (refl a) = refl (f a)
|
||||
-- := refl (refl (f a))
|
||||
|
||||
infixr `×`:30 := product
|
||||
infixr `∧`:30 := product
|
||||
-- section
|
||||
-- parameters {A : Type} {B : Type} {C : Type}
|
||||
-- parameters (f : A → B) (g : B → C)
|
||||
-- parameters (x y z : A) (p : x = y) (q : y = z)
|
||||
|
||||
notation `(` h `,` t:(foldl `,` (e r, pair r e) h) `)` := t
|
||||
-- theorem ap_trans_dist : ap f (p ⬝ q) = (ap f p) ⬝ (ap f q)
|
||||
-- := have e1 : ap f (p ⬝ refl y) = (ap f p) ⬝ (ap f (refl y)), from refl _,
|
||||
-- path_rec e1 q
|
||||
|
||||
definition pr1 {A : Type} {B : Type} (p : A × B) : A
|
||||
:= product_rec (λ a b, a) p
|
||||
-- theorem ap_inv_dist : ap f (p⁻¹) = (ap f p)⁻¹
|
||||
-- := have e1 : ap f ((refl x)⁻¹) = (ap f (refl x))⁻¹, from refl _,
|
||||
-- path_rec e1 p
|
||||
|
||||
definition pr2 {A : Type} {B : Type} (p : A × B) : B
|
||||
:= product_rec (λ a b, b) p
|
||||
-- theorem ap_compose : ap g (ap f p) = ap (g∘f) p
|
||||
-- := have e1 : ap g (ap f (refl x)) = ap (g∘f) (refl x), from refl _,
|
||||
-- path_rec e1 p
|
||||
|
||||
theorem uppt {A : Type} {B : Type} (p : A × B) : (pr1 p, pr2 p) = p
|
||||
:= product_rec (λ x y, refl (x, y)) p
|
||||
-- theorem ap_id : ap id p = p
|
||||
-- := have e1 : ap id (refl x) = (refl x), from refl (refl x),
|
||||
-- path_rec e1 p
|
||||
-- end
|
||||
|
||||
inductive sum (A : Type) (B : Type) : Type :=
|
||||
| inl : A → sum A B
|
||||
| inr : B → sum A B
|
||||
-- section
|
||||
-- parameters {A : Type} {B : A → Type} (f : Π x, B x)
|
||||
-- definition D [private] (x y : A) (p : x = y) := p*(f x) = f y
|
||||
-- definition d [private] (x : A) : D x x (refl x)
|
||||
-- := refl (f x)
|
||||
|
||||
namespace logic
|
||||
infixr `+`:25 := sum
|
||||
end logic
|
||||
using logic
|
||||
infixr `∨`:25 := sum
|
||||
-- theorem apd {a b : A} (p : a = b) : p*(f a) = f b
|
||||
-- := path_rec (d a) p
|
||||
-- end
|
||||
|
||||
theorem sum_elim {a : Type} {b : Type} {c : Type} (H1 : a + b) (H2 : a → c) (H3 : b → c) : c
|
||||
:= sum_rec H2 H3 H1
|
||||
|
||||
theorem resolve_right {a : Type} {b : Type} (H1 : a + b) (H2 : ¬ a) : b
|
||||
:= sum_elim H1 (assume Ha, absurd_elim b Ha H2) (assume Hb, Hb)
|
||||
-- abbreviation homotopy {A : Type} {P : A → Type} (f g : Π x, P x)
|
||||
-- := Π x, f x = g x
|
||||
|
||||
theorem resolve_left {a : Type} {b : Type} (H1 : a + b) (H2 : ¬ b) : a
|
||||
:= sum_elim H1 (assume Ha, Ha) (assume Hb, absurd_elim a Hb H2)
|
||||
-- namespace logic
|
||||
-- infix `∼`:50 := homotopy
|
||||
-- end
|
||||
-- using logic
|
||||
|
||||
theorem sum_flip {a : Type} {b : Type} (H : a + b) : b + a
|
||||
:= sum_elim H (assume Ha, inr b Ha) (assume Hb, inl a Hb)
|
||||
-- notation `assume` binders `,` r:(scoped f, f) := r
|
||||
-- notation `take` binders `,` r:(scoped f, f) := r
|
||||
|
||||
inductive Sigma {A : Type} (B : A → Type) : Type :=
|
||||
| sigma_intro : Π a, B a → Sigma B
|
||||
-- section
|
||||
-- parameters {A : Type} {B : Type}
|
||||
|
||||
notation `Σ` binders `,` r:(scoped P, Sigma P) := r
|
||||
-- theorem hom_refl (f : A → B) : f ∼ f
|
||||
-- := take x, refl (f x)
|
||||
|
||||
definition dpr1 {A : Type} {B : A → Type} (p : Σ x, B x) : A
|
||||
:= Sigma_rec (λ a b, a) p
|
||||
-- theorem hom_symm {f g : A → B} : f ∼ g → g ∼ f
|
||||
-- := assume h, take x, (h x)⁻¹
|
||||
|
||||
definition dpr2 {A : Type} {B : A → Type} (p : Σ x, B x) : B (dpr1 p)
|
||||
:= Sigma_rec (λ a b, b) p
|
||||
-- theorem hom_trans {f g h : A → B} : f ∼ g → g ∼ h → f ∼ h
|
||||
-- := assume h1 h2, take x, (h1 x) ⬝ (h2 x)
|
||||
|
||||
-- theorem hom_fun {f g : A → B} {x y : A} (H : f ∼ g) (p : x = y) : (H x) ⬝ (ap g p) = (ap f p) ⬝ (H y)
|
||||
-- := have e1 : (H x) ⬝ (refl (g x)) = (refl (f x)) ⬝ (H x), from
|
||||
-- calc (H x) ⬝ (refl (g x)) = H x : (trans_refl_right (H x))⁻¹
|
||||
-- ... = (refl (f x)) ⬝ (H x) : trans_refl_left (H x),
|
||||
-- have e2 : (H x) ⬝ (ap g (refl x)) = (ap f (refl x)) ⬝ (H x), from
|
||||
-- calc (H x) ⬝ (ap g (refl x)) = (H x) ⬝ (refl (g x)) : {ap_refl g x}
|
||||
-- ... = (refl (f x)) ⬝ (H x) : e1
|
||||
-- ... = (ap f (refl x)) ⬝ (H x) : {symm (ap_refl f x)},
|
||||
-- path_rec e2 p
|
||||
|
||||
|
||||
-- end
|
||||
|
||||
-- definition loop_space (A : Type) (a : A) := a = a
|
||||
-- notation `Ω` `(` A `,` a `)` := loop_space A a
|
||||
|
||||
-- definition loop2d_space (A : Type) (a : A) := (refl a) = (refl a)
|
||||
-- notation `Ω²` `(` A `,` a `)` := loop2d_space A a
|
||||
|
||||
-- inductive empty : Type
|
||||
|
||||
-- theorem empty_elim (c : Type) (H : empty) : c
|
||||
-- := empty_rec (λ e, c) H
|
||||
|
||||
-- definition not (A : Type) := A → empty
|
||||
-- prefix `¬`:40 := not
|
||||
|
||||
-- theorem not_intro {a : Type} (H : a → empty) : ¬ a
|
||||
-- := H
|
||||
|
||||
-- theorem not_elim {a : Type} (H1 : ¬ a) (H2 : a) : empty
|
||||
-- := H1 H2
|
||||
|
||||
-- theorem absurd {a : Type} (H1 : a) (H2 : ¬ a) : empty
|
||||
-- := H2 H1
|
||||
|
||||
-- theorem mt {a b : Type} (H1 : a → b) (H2 : ¬ b) : ¬ a
|
||||
-- := assume Ha : a, absurd (H1 Ha) H2
|
||||
|
||||
-- theorem contrapos {a b : Type} (H : a → b) : ¬ b → ¬ a
|
||||
-- := assume Hnb : ¬ b, mt H Hnb
|
||||
|
||||
-- theorem absurd_elim {a : Type} (b : Type) (H1 : a) (H2 : ¬ a) : b
|
||||
-- := empty_elim b (absurd H1 H2)
|
||||
|
||||
-- inductive unit : Type :=
|
||||
-- | star : unit
|
||||
|
||||
-- notation `⋆`:max := star
|
||||
|
||||
-- theorem absurd_not_unit (H : ¬ unit) : empty
|
||||
-- := absurd star H
|
||||
|
||||
-- theorem not_empty_trivial : ¬ empty
|
||||
-- := assume H : empty, H
|
||||
|
||||
-- theorem upun (x : unit) : x = ⋆
|
||||
-- := unit_rec (refl ⋆) x
|
||||
|
||||
-- inductive product (A : Type) (B : Type) : Type :=
|
||||
-- | pair : A → B → product A B
|
||||
|
||||
-- infixr `×`:30 := product
|
||||
-- infixr `∧`:30 := product
|
||||
|
||||
-- notation `(` h `,` t:(foldl `,` (e r, pair r e) h) `)` := t
|
||||
|
||||
-- definition pr1 {A : Type} {B : Type} (p : A × B) : A
|
||||
-- := product_rec (λ a b, a) p
|
||||
|
||||
-- definition pr2 {A : Type} {B : Type} (p : A × B) : B
|
||||
-- := product_rec (λ a b, b) p
|
||||
|
||||
-- theorem uppt {A : Type} {B : Type} (p : A × B) : (pr1 p, pr2 p) = p
|
||||
-- := product_rec (λ x y, refl (x, y)) p
|
||||
|
||||
-- inductive sum (A : Type) (B : Type) : Type :=
|
||||
-- | inl : A → sum A B
|
||||
-- | inr : B → sum A B
|
||||
|
||||
-- namespace logic
|
||||
-- infixr `+`:25 := sum
|
||||
-- end
|
||||
-- using logic
|
||||
-- infixr `∨`:25 := sum
|
||||
|
||||
-- theorem sum_elim {a : Type} {b : Type} {c : Type} (H1 : a + b) (H2 : a → c) (H3 : b → c) : c
|
||||
-- := sum_rec H2 H3 H1
|
||||
|
||||
-- theorem resolve_right {a : Type} {b : Type} (H1 : a + b) (H2 : ¬ a) : b
|
||||
-- := sum_elim H1 (assume Ha, absurd_elim b Ha H2) (assume Hb, Hb)
|
||||
|
||||
-- theorem resolve_left {a : Type} {b : Type} (H1 : a + b) (H2 : ¬ b) : a
|
||||
-- := sum_elim H1 (assume Ha, Ha) (assume Hb, absurd_elim a Hb H2)
|
||||
|
||||
-- theorem sum_flip {a : Type} {b : Type} (H : a + b) : b + a
|
||||
-- := sum_elim H (assume Ha, inr b Ha) (assume Hb, inl a Hb)
|
||||
|
||||
-- inductive Sigma {A : Type} (B : A → Type) : Type :=
|
||||
-- | sigma_intro : Π a, B a → Sigma B
|
||||
|
||||
-- notation `Σ` binders `,` r:(scoped P, Sigma P) := r
|
||||
|
||||
-- definition dpr1 {A : Type} {B : A → Type} (p : Σ x, B x) : A
|
||||
-- := Sigma_rec (λ a b, a) p
|
||||
|
||||
-- definition dpr2 {A : Type} {B : A → Type} (p : Σ x, B x) : B (dpr1 p)
|
||||
-- := Sigma_rec (λ a b, b) p
|
||||
|
|
922
library/hott/path_groupoids.lean
Normal file
922
library/hott/path_groupoids.lean
Normal file
|
@ -0,0 +1,922 @@
|
|||
-- Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
||||
-- Released under Apache 2.0 license as described in the file LICENSE.
|
||||
-- Author: Jeremy Avigad
|
||||
-- Ported from Coq HoTT
|
||||
|
||||
import .logic .tactic
|
||||
|
||||
using tactic
|
||||
|
||||
-- Path
|
||||
-- ----
|
||||
|
||||
inductive path {A : Type} (a : A) : A → Type :=
|
||||
| idpath : path a a
|
||||
|
||||
infix `≈`:50 := path
|
||||
notation x `≈` y:50 `:>`:0 A:0 := @path A x y -- TODO: is this right?
|
||||
notation `idp`:max := idpath _ -- TODO: can we / should we use `1`?
|
||||
|
||||
namespace path
|
||||
abbreviation induction_on {A : Type} {a b : A} (p : a ≈ b)
|
||||
{C : Π (b : A) (p : a ≈ b), Type} (H : C a (idpath a)) : C b p :=
|
||||
path_rec H p
|
||||
end path
|
||||
|
||||
|
||||
-- TODO: should all this be in namespace path?
|
||||
using path
|
||||
|
||||
-- Concatenation and inverse
|
||||
-- -------------------------
|
||||
|
||||
definition concat {A : Type} {x y z : A} (p : x ≈ y) (q : y ≈ z) : x ≈ z :=
|
||||
path_rec (λu, u) q p
|
||||
|
||||
-- TODO: should this be an abbreviation?
|
||||
definition inverse {A : Type} {x y : A} (p : x ≈ y) : y ≈ x :=
|
||||
path_rec (idpath x) p
|
||||
|
||||
infixl `@`:75 := concat
|
||||
postfix `^`:100 := inverse
|
||||
|
||||
-- In Coq, these are not needed, because concat and inv are kept transparent
|
||||
definition inv_1 {A : Type} (x : A) : (idpath x)^ ≈ idpath x := idp
|
||||
|
||||
definition concat_11 {A : Type} (x : A) : idpath x @ idpath x ≈ idpath x := idp
|
||||
|
||||
|
||||
-- The 1-dimensional groupoid structure
|
||||
-- ------------------------------------
|
||||
|
||||
-- The identity path is a right unit.
|
||||
definition concat_p1 {A : Type} {x y : A} (p : x ≈ y) : p @ idp ≈ p :=
|
||||
induction_on p idp
|
||||
|
||||
-- The identity path is a right unit.
|
||||
definition concat_1p {A : Type} {x y : A} (p : x ≈ y) : idp @ p ≈ p :=
|
||||
induction_on p idp
|
||||
|
||||
-- Concatenation is associative.
|
||||
definition concat_p_pp {A : Type} {x y z t : A} (p : x ≈ y) (q : y ≈ z) (r : z ≈ t) :
|
||||
p @ (q @ r) ≈ (p @ q) @ r :=
|
||||
induction_on r (induction_on q idp)
|
||||
|
||||
definition concat_pp_p {A : Type} {x y z t : A} (p : x ≈ y) (q : y ≈ z) (r : z ≈ t) :
|
||||
(p @ q) @ r ≈ p @ (q @ r) :=
|
||||
induction_on r (induction_on q idp)
|
||||
|
||||
-- The left inverse law.
|
||||
definition concat_pV {A : Type} {x y : A} (p : x ≈ y) : p @ p^ ≈ idp :=
|
||||
induction_on p idp
|
||||
|
||||
-- The right inverse law.
|
||||
definition concat_Vp {A : Type} {x y : A} (p : x ≈ y) : p^ @ p ≈ idp :=
|
||||
induction_on p idp
|
||||
|
||||
|
||||
-- Several auxiliary theorems about canceling inverses across associativity. These are somewhat
|
||||
-- redundant, following from earlier theorems.
|
||||
|
||||
definition concat_V_pp {A : Type} {x y z : A} (p : x ≈ y) (q : y ≈ z) : p^ @ (p @ q) ≈ q :=
|
||||
induction_on q (induction_on p idp)
|
||||
|
||||
definition concat_p_Vp {A : Type} {x y z : A} (p : x ≈ y) (q : x ≈ z) : p @ (p^ @ q) ≈ q :=
|
||||
induction_on q (induction_on p idp)
|
||||
|
||||
definition concat_pp_V {A : Type} {x y z : A} (p : x ≈ y) (q : y ≈ z) : (p @ q) @ q^ ≈ p :=
|
||||
induction_on q (induction_on p idp)
|
||||
|
||||
definition concat_pV_p {A : Type} {x y z : A} (p : x ≈ z) (q : y ≈ z) : (p @ q^) @ q ≈ p :=
|
||||
induction_on q (take p, induction_on p idp) p
|
||||
|
||||
-- Inverse distributes over concatenation
|
||||
definition inv_pp {A : Type} {x y z : A} (p : x ≈ y) (q : y ≈ z) : (p @ q)^ ≈ q^ @ p^ :=
|
||||
induction_on q (induction_on p idp)
|
||||
|
||||
definition inv_Vp {A : Type} {x y z : A} (p : y ≈ x) (q : y ≈ z) : (p^ @ q)^ ≈ q^ @ p :=
|
||||
induction_on q (induction_on p idp)
|
||||
|
||||
-- universe metavariables
|
||||
definition inv_pV {A : Type} {x y z : A} (p : x ≈ y) (q : z ≈ y) : (p @ q^)^ ≈ q @ p^ :=
|
||||
induction_on p (λq, induction_on q idp) q
|
||||
|
||||
definition inv_VV {A : Type} {x y z : A} (p : y ≈ x) (q : z ≈ y) : (p^ @ q^)^ ≈ q @ p :=
|
||||
induction_on p (induction_on q idp)
|
||||
|
||||
-- Inverse is an involution.
|
||||
definition inv_V {A : Type} {x y : A} (p : x ≈ y) : p^^ ≈ p :=
|
||||
induction_on p idp
|
||||
|
||||
|
||||
-- Theorems for moving things around in equations
|
||||
-- ----------------------------------------------
|
||||
|
||||
definition moveR_Mp {A : Type} {x y z : A} (p : x ≈ z) (q : y ≈ z) (r : y ≈ x) :
|
||||
p ≈ (r^ @ q) → (r @ p) ≈ q :=
|
||||
have gen : Πp q, p ≈ (r^ @ q) → (r @ p) ≈ q, from
|
||||
induction_on r
|
||||
(take p q,
|
||||
assume h : p ≈ idp^ @ q,
|
||||
show idp @ p ≈ q, from concat_1p _ @ h @ concat_1p _),
|
||||
gen p q
|
||||
|
||||
definition moveR_pM {A : Type} {x y z : A} (p : x ≈ z) (q : y ≈ z) (r : y ≈ x) :
|
||||
r ≈ q @ p^ → r @ p ≈ q :=
|
||||
induction_on p (take q r h, (concat_p1 _ @ h @ concat_p1 _)) q r
|
||||
|
||||
definition moveR_Vp {A : Type} {x y z : A} (p : x ≈ z) (q : y ≈ z) (r : x ≈ y) :
|
||||
p ≈ r @ q → r^ @ p ≈ q :=
|
||||
induction_on r (take p q h, concat_1p _ @ h @ concat_1p _) p q
|
||||
|
||||
definition moveR_pV {A : Type} {x y z : A} (p : z ≈ x) (q : y ≈ z) (r : y ≈ x) :
|
||||
r ≈ q @ p → r @ p^ ≈ q :=
|
||||
induction_on p (take q r h, concat_p1 _ @ h @ concat_p1 _) q r
|
||||
|
||||
definition moveL_Mp {A : Type} {x y z : A} (p : x ≈ z) (q : y ≈ z) (r : y ≈ x) :
|
||||
r^ @ q ≈ p → q ≈ r @ p :=
|
||||
induction_on r (take p q h, (concat_1p _)^ @ h @ (concat_1p _)^) p q
|
||||
|
||||
definition moveL_pM {A : Type} {x y z : A} (p : x ≈ z) (q : y ≈ z) (r : y ≈ x) :
|
||||
q @ p^ ≈ r → q ≈ r @ p :=
|
||||
induction_on p (take q r h, (concat_p1 _)^ @ h @ (concat_p1 _)^) q r
|
||||
|
||||
definition moveL_Vp {A : Type} {x y z : A} (p : x ≈ z) (q : y ≈ z) (r : x ≈ y) :
|
||||
r @ q ≈ p → q ≈ r^ @ p :=
|
||||
induction_on r (take p q h, (concat_1p _)^ @ h @ (concat_1p _)^) p q
|
||||
|
||||
definition moveL_pV {A : Type} {x y z : A} (p : z ≈ x) (q : y ≈ z) (r : y ≈ x) :
|
||||
q @ p ≈ r → q ≈ r @ p^ :=
|
||||
induction_on p (take q r h, (concat_p1 _)^ @ h @ (concat_p1 _)^) q r
|
||||
|
||||
definition moveL_1M {A : Type} {x y : A} (p q : x ≈ y) :
|
||||
p @ q^ ≈ idp → p ≈ q :=
|
||||
induction_on q (take p h, (concat_p1 _)^ @ h) p
|
||||
|
||||
definition moveL_M1 {A : Type} {x y : A} (p q : x ≈ y) :
|
||||
q^ @ p ≈ idp → p ≈ q :=
|
||||
induction_on q (take p h, (concat_1p _)^ @ h) p
|
||||
|
||||
definition moveL_1V {A : Type} {x y : A} (p : x ≈ y) (q : y ≈ x) :
|
||||
p @ q ≈ idp → p ≈ q^ :=
|
||||
induction_on q (take p h, (concat_p1 _)^ @ h) p
|
||||
|
||||
definition moveL_V1 {A : Type} {x y : A} (p : x ≈ y) (q : y ≈ x) :
|
||||
q @ p ≈ idp → p ≈ q^ :=
|
||||
induction_on q (take p h, (concat_1p _)^ @ h) p
|
||||
|
||||
definition moveR_M1 {A : Type} {x y : A} (p q : x ≈ y) :
|
||||
idp ≈ p^ @ q → p ≈ q :=
|
||||
induction_on p (take q h, h @ (concat_1p _)) q
|
||||
|
||||
definition moveR_1M {A : Type} {x y : A} (p q : x ≈ y) :
|
||||
idp ≈ q @ p^ → p ≈ q :=
|
||||
induction_on p (take q h, h @ (concat_p1 _)) q
|
||||
|
||||
definition moveR_1V {A : Type} {x y : A} (p : x ≈ y) (q : y ≈ x) :
|
||||
idp ≈ q @ p → p^ ≈ q :=
|
||||
induction_on p (take q h, h @ (concat_p1 _)) q
|
||||
|
||||
definition moveR_V1 {A : Type} {x y : A} (p : x ≈ y) (q : y ≈ x) :
|
||||
idp ≈ p @ q → p^ ≈ q :=
|
||||
induction_on p (take q h, h @ (concat_1p _)) q
|
||||
|
||||
|
||||
-- Transport
|
||||
-- ---------
|
||||
|
||||
-- keep transparent, so transport _ idp p is definitionally equal to p
|
||||
abbreviation transport {A : Type} (P : A → Type) {x y : A} (p : x ≈ y) (u : P x) : P y :=
|
||||
path.induction_on p u
|
||||
|
||||
definition transport_1 {A : Type} (P : A → Type) {x : A} (u : P x) : transport _ idp u ≈ u :=
|
||||
idp
|
||||
|
||||
-- This idiom makes the operation right associative.
|
||||
notation p `#`:65 x:64 := transport _ p x
|
||||
|
||||
definition ap ⦃A B : Type⦄ (f : A → B) {x y:A} (p : x ≈ y) : f x ≈ f y :=
|
||||
path.induction_on p idp
|
||||
|
||||
-- TODO: is this better than an alias? Note use of curly brackets
|
||||
abbreviation ap01 := ap
|
||||
|
||||
abbreviation pointwise_paths {A : Type} {P : A → Type} (f g : Πx, P x) : Type :=
|
||||
Πx : A, f x ≈ g x
|
||||
|
||||
infix `∼`:50 := pointwise_paths
|
||||
|
||||
definition apD10 {A} {B : A → Type} {f g : Πx, B x} (H : f ≈ g) : f ∼ g :=
|
||||
λx, path.induction_on H idp
|
||||
|
||||
definition ap10 {A B} {f g : A → B} (H : f ≈ g) : f ∼ g := apD10 H
|
||||
|
||||
definition ap11 {A B} {f g : A → B} (H : f ≈ g) {x y : A} (p : x ≈ y) : f x ≈ g y :=
|
||||
induction_on H (induction_on p idp)
|
||||
|
||||
definition apD {A:Type} {B : A → Type} (f : Πa:A, B a) {x y : A} (p : x ≈ y) : p # (f x) ≈ f y :=
|
||||
induction_on p idp
|
||||
|
||||
|
||||
-- More theorems for moving things around in equations
|
||||
-- ---------------------------------------------------
|
||||
|
||||
definition moveR_transport_p {A : Type} (P : A → Type) {x y : A} (p : x ≈ y) (u : P x) (v : P y) :
|
||||
u ≈ p^ # v → p # u ≈ v :=
|
||||
induction_on p (take u v, id) u v
|
||||
|
||||
definition moveR_transport_V {A : Type} (P : A → Type) {x y : A} (p : y ≈ x) (u : P x) (v : P y) :
|
||||
u ≈ p # v → p^ # u ≈ v :=
|
||||
induction_on p (take u v, id) u v
|
||||
|
||||
definition moveL_transport_V {A : Type} (P : A → Type) {x y : A} (p : x ≈ y) (u : P x) (v : P y) :
|
||||
p # u ≈ v → u ≈ p^ # v :=
|
||||
induction_on p (take u v, id) u v
|
||||
|
||||
definition moveL_transport_p {A : Type} (P : A → Type) {x y : A} (p : y ≈ x) (u : P x) (v : P y) :
|
||||
p^ # u ≈ v → u ≈ p # v :=
|
||||
induction_on p (take u v, id) u v
|
||||
|
||||
|
||||
-- Functoriality of functions
|
||||
-- --------------------------
|
||||
|
||||
-- Here we prove that functions behave like functors between groupoids, and that [ap] itself is
|
||||
-- functorial.
|
||||
|
||||
-- Functions take identity paths to identity paths
|
||||
definition ap_1 {A B : Type} (x : A) (f : A → B) : (ap f idp) ≈ idp :> (f x ≈ f x) := idp
|
||||
|
||||
definition apD_1 {A B} (x : A) (f : forall x : A, B x) : apD f idp ≈ idp :> (f x ≈ f x) := idp
|
||||
|
||||
-- Functions commute with concatenation.
|
||||
definition ap_pp {A B : Type} (f : A → B) {x y z : A} (p : x ≈ y) (q : y ≈ z) :
|
||||
ap f (p @ q) ≈ (ap f p) @ (ap f q) :=
|
||||
induction_on q (induction_on p idp)
|
||||
|
||||
definition ap_p_pp {A B : Type} (f : A → B) {w x y z : A} (r : f w ≈ f x) (p : x ≈ y) (q : y ≈ z) :
|
||||
r @ (ap f (p @ q)) ≈ (r @ ap f p) @ (ap f q) :=
|
||||
induction_on p (take r q, induction_on q (concat_p_pp r idp idp)) r q
|
||||
|
||||
definition ap_pp_p {A B : Type} (f : A → B) {w x y z : A} (p : x ≈ y) (q : y ≈ z) (r : f z ≈ f w) :
|
||||
(ap f (p @ q)) @ r ≈ (ap f p) @ (ap f q @ r) :=
|
||||
induction_on p (take q, induction_on q (take r, concat_pp_p _ _ _)) q r
|
||||
-- induction_on p (take q : x ≈ z, induction_on q (take r : f x ≈ f w, concat_pp_p idp idp r)) q r
|
||||
|
||||
-- TODO: can we do this proof using tactics?
|
||||
-- proof
|
||||
-- apply (induction_on p _ q r),
|
||||
-- apply (take q, induction_on q _),
|
||||
-- apply (concat_pp_p idp idp r)
|
||||
-- qed
|
||||
|
||||
-- proof
|
||||
-- apply (induction_on p _ q r),
|
||||
-- take q, proof
|
||||
-- apply (induction_on q),
|
||||
-- take r,
|
||||
-- apply concat_pp_p
|
||||
-- qed
|
||||
-- qed
|
||||
|
||||
-- Coq proof:
|
||||
-- Proof.
|
||||
-- destruct p, q. simpl. exact (concat_pp_p idp idp r).
|
||||
-- Defined.
|
||||
|
||||
-- Functions commute with path inverses.
|
||||
definition inverse_ap {A B : Type} (f : A → B) {x y : A} (p : x ≈ y) : (ap f p)^ ≈ ap f (p^) :=
|
||||
induction_on p idp
|
||||
|
||||
definition ap_V {A B : Type} (f : A → B) {x y : A} (p : x ≈ y) : ap f (p^) ≈ (ap f p)^ :=
|
||||
induction_on p idp
|
||||
|
||||
-- [ap] itself is functorial in the first argument.
|
||||
|
||||
-- TODO: rename id to idmap?
|
||||
definition ap_idmap {A : Type} {x y : A} (p : x ≈ y) : ap id p ≈ p :=
|
||||
induction_on p idp
|
||||
|
||||
definition ap_compose {A B C : Type} (f : A → B) (g : B → C) {x y : A} (p : x ≈ y) :
|
||||
ap (g ∘ f) p ≈ ap g (ap f p) :=
|
||||
induction_on p idp
|
||||
|
||||
-- Sometimes we don't have the actual function [compose].
|
||||
definition ap_compose' {A B C : Type} (f : A → B) (g : B → C) {x y : A} (p : x ≈ y) :
|
||||
ap (λa, g (f a)) p ≈ ap g (ap f p) :=
|
||||
induction_on p idp
|
||||
|
||||
-- The action of constant maps.
|
||||
definition ap_const {A B : Type} {x y : A} (p : x ≈ y) (z : B) :
|
||||
ap (λu, z) p ≈ idp :=
|
||||
induction_on p idp
|
||||
|
||||
-- Naturality of [ap].
|
||||
definition concat_Ap {A B : Type} {f g : A → B} (p : forall x, f x ≈ g x) {x y : A} (q : x ≈ y) :
|
||||
(ap f q) @ (p y) ≈ (p x) @ (ap g q) :=
|
||||
induction_on q (concat_1p _ @ (concat_p1 _)^)
|
||||
|
||||
-- Naturality of [ap] at identity.
|
||||
definition concat_A1p {A : Type} {f : A → A} (p : forall x, f x ≈ x) {x y : A} (q : x ≈ y) :
|
||||
(ap f q) @ (p y) ≈ (p x) @ q :=
|
||||
induction_on q (concat_1p _ @ (concat_p1 _)^)
|
||||
|
||||
definition concat_pA1 {A : Type} {f : A → A} (p : forall x, x ≈ f x) {x y : A} (q : x ≈ y) :
|
||||
(p x) @ (ap f q) ≈ q @ (p y) :=
|
||||
induction_on q (concat_p1 _ @ (concat_1p _)^)
|
||||
|
||||
-- TODO: move these
|
||||
calc_subst transport
|
||||
calc_trans concat
|
||||
calc_refl idpath
|
||||
|
||||
-- Naturality with other paths hanging around.
|
||||
|
||||
definition concat_pA_pp {A B : Type} {f g : A → B} (p : forall x, f x ≈ g x)
|
||||
{x y : A} (q : x ≈ y)
|
||||
{w z : B} (r : w ≈ f x) (s : g y ≈ z) :
|
||||
(r @ ap f q) @ (p y @ s) ≈ (r @ p x) @ (ap g q @ s) :=
|
||||
induction_on q (induction_on s
|
||||
(calc
|
||||
(r @ (ap f q)) @ ((p y) @ (idpath (g y))) ≈ (r @ (ap f q)) @ (p y) : {concat_p1 _}
|
||||
... ≈ r @ ((ap f q) @ (p y)) : concat_pp_p _ _ _
|
||||
... ≈ r @ ((p x) @ (ap g q)) : {concat_Ap p q}
|
||||
... ≈ (r @ (p x)) @ ((ap g q)) : concat_p_pp _ _ _
|
||||
... ≈ (r @ (p x)) @ ((ap g q) @ (idpath (g y))) : {concat_p1 _}))
|
||||
|
||||
-- TODO: the Coq proof of the previous theorem is much shorter:
|
||||
-- Proof.
|
||||
-- destruct q, s; simpl.
|
||||
-- repeat rewrite concat_p1.
|
||||
-- reflexivity.
|
||||
-- Defined.
|
||||
|
||||
(-- TODO: These are similar
|
||||
|
||||
definition concat_pA_p {A B : Type} {f g : A → B} (p : forall x, f x ≈ g x)
|
||||
{x y : A} (q : x ≈ y)
|
||||
{w : B} (r : w ≈ f x)
|
||||
:
|
||||
(r @ ap f q) @ p y ≈ (r @ p x) @ ap g q.
|
||||
Proof.
|
||||
destruct q; simpl.
|
||||
repeat rewrite concat_p1.
|
||||
reflexivity.
|
||||
Defined.
|
||||
|
||||
definition concat_A_pp {A B : Type} {f g : A → B} (p : forall x, f x ≈ g x)
|
||||
{x y : A} (q : x ≈ y)
|
||||
{z : B} (s : g y ≈ z)
|
||||
:
|
||||
(ap f q) @ (p y @ s) ≈ (p x) @ (ap g q @ s).
|
||||
Proof.
|
||||
destruct q, s; simpl.
|
||||
repeat rewrite concat_p1, concat_1p.
|
||||
reflexivity.
|
||||
Defined.
|
||||
|
||||
definition concat_pA1_pp {A : Type} {f : A → A} (p : forall x, f x ≈ x)
|
||||
{x y : A} (q : x ≈ y)
|
||||
{w z : A} (r : w ≈ f x) (s : y ≈ z)
|
||||
:
|
||||
(r @ ap f q) @ (p y @ s) ≈ (r @ p x) @ (q @ s).
|
||||
Proof.
|
||||
destruct q, s; simpl.
|
||||
repeat rewrite concat_p1.
|
||||
reflexivity.
|
||||
Defined.
|
||||
|
||||
definition concat_pp_A1p {A : Type} {g : A → A} (p : forall x, x ≈ g x)
|
||||
{x y : A} (q : x ≈ y)
|
||||
{w z : A} (r : w ≈ x) (s : g y ≈ z)
|
||||
:
|
||||
(r @ p x) @ (ap g q @ s) ≈ (r @ q) @ (p y @ s).
|
||||
Proof.
|
||||
destruct q, s; simpl.
|
||||
repeat rewrite concat_p1.
|
||||
reflexivity.
|
||||
Defined.
|
||||
|
||||
definition concat_pA1_p {A : Type} {f : A → A} (p : forall x, f x ≈ x)
|
||||
{x y : A} (q : x ≈ y)
|
||||
{w : A} (r : w ≈ f x)
|
||||
:
|
||||
(r @ ap f q) @ p y ≈ (r @ p x) @ q.
|
||||
Proof.
|
||||
destruct q; simpl.
|
||||
repeat rewrite concat_p1.
|
||||
reflexivity.
|
||||
Defined.
|
||||
|
||||
definition concat_A1_pp {A : Type} {f : A → A} (p : forall x, f x ≈ x)
|
||||
{x y : A} (q : x ≈ y)
|
||||
{z : A} (s : y ≈ z)
|
||||
:
|
||||
(ap f q) @ (p y @ s) ≈ (p x) @ (q @ s).
|
||||
Proof.
|
||||
destruct q, s; simpl.
|
||||
repeat rewrite concat_p1, concat_1p.
|
||||
reflexivity.
|
||||
Defined.
|
||||
|
||||
definition concat_pp_A1 {A : Type} {g : A → A} (p : forall x, x ≈ g x)
|
||||
{x y : A} (q : x ≈ y)
|
||||
{w : A} (r : w ≈ x)
|
||||
:
|
||||
(r @ p x) @ ap g q ≈ (r @ q) @ p y.
|
||||
Proof.
|
||||
destruct q; simpl.
|
||||
repeat rewrite concat_p1.
|
||||
reflexivity.
|
||||
Defined.
|
||||
|
||||
definition concat_p_A1p {A : Type} {g : A → A} (p : forall x, x ≈ g x)
|
||||
{x y : A} (q : x ≈ y)
|
||||
{z : A} (s : g y ≈ z)
|
||||
:
|
||||
p x @ (ap g q @ s) ≈ q @ (p y @ s).
|
||||
Proof.
|
||||
destruct q, s; simpl.
|
||||
repeat rewrite concat_p1, concat_1p.
|
||||
reflexivity.
|
||||
Defined.
|
||||
--)
|
||||
|
||||
|
||||
-- Action of [apD10] and [ap10] on paths
|
||||
-- -------------------------------------
|
||||
|
||||
-- Application of paths between functions preserves the groupoid structure
|
||||
|
||||
definition apD10_1 {A} {B : A → Type} (f : Πx, B x) (x : A) : apD10 (idpath f) x ≈ idp := idp
|
||||
|
||||
definition apD10_pp {A} {B : A → Type} {f f' f'' : Πx, B x} (h : f ≈ f') (h' : f' ≈ f'') (x : A) :
|
||||
apD10 (h @ h') x ≈ apD10 h x @ apD10 h' x :=
|
||||
induction_on h (take h', induction_on h' idp) h'
|
||||
|
||||
definition apD10_V {A : Type} {B : A → Type} {f g : Πx : A, B x} (h : f ≈ g) (x : A) :
|
||||
apD10 (h^) x ≈ (apD10 h x)^ :=
|
||||
induction_on h idp
|
||||
|
||||
definition ap10_1 {A B} {f : A → B} (x : A) : ap10 (idpath f) x ≈ idp := idp
|
||||
|
||||
definition ap10_pp {A B} {f f' f'' : A → B} (h : f ≈ f') (h' : f' ≈ f'') (x : A) :
|
||||
ap10 (h @ h') x ≈ ap10 h x @ ap10 h' x := apD10_pp h h' x
|
||||
|
||||
definition ap10_V {A B} {f g : A→B} (h : f ≈ g) (x:A) : ap10 (h^) x ≈ (ap10 h x)^ := apD10_V h x
|
||||
|
||||
-- [ap10] also behaves nicely on paths produced by [ap]
|
||||
definition ap_ap10 {A B C} (f g : A → B) (h : B → C) (p : f ≈ g) (a : A) :
|
||||
ap h (ap10 p a) ≈ ap10 (ap (λ f', h ∘ f') p) a:=
|
||||
induction_on p idp
|
||||
|
||||
|
||||
-- Transport and the groupoid structure of paths
|
||||
-- ---------------------------------------------
|
||||
|
||||
-- TODO: move from above?
|
||||
-- definition transport_1 {A : Type} (P : A → Type) {x : A} (u : P x)
|
||||
-- : idp # u ≈ u := idp
|
||||
|
||||
definition transport_pp {A : Type} (P : A → Type) {x y z : A} (p : x ≈ y) (q : y ≈ z) (u : P x) :
|
||||
p @ q # u ≈ q # p # u :=
|
||||
induction_on q (induction_on p idp)
|
||||
|
||||
definition transport_pV {A : Type} (P : A → Type) {x y : A} (p : x ≈ y) (z : P y) :
|
||||
p # p^ # z ≈ z :=
|
||||
(transport_pp P (p^) p z)^ @ ap (λr, transport P r z) (concat_Vp p)
|
||||
|
||||
definition transport_Vp {A : Type} (P : A → Type) {x y : A} (p : x ≈ y) (z : P x) :
|
||||
p^ # p # z ≈ z :=
|
||||
(transport_pp P p (p^) z)^ @ ap (λr, transport P r z) (concat_pV p)
|
||||
|
||||
|
||||
-----------------------------------------------
|
||||
-- TODO: Examples of difficult induction problems
|
||||
-----------------------------------------------
|
||||
|
||||
theorem double_induction
|
||||
{A : Type} {x y z : A} (p : x ≈ y) (q : y ≈ z)
|
||||
{C : Π(x y z : A), Π(p : x ≈ y), Π(q : y ≈ z), Type}
|
||||
(H : C x x x (idpath x) (idpath x)) :
|
||||
C x y z p q :=
|
||||
induction_on p (take z q, induction_on q H) z q
|
||||
|
||||
theorem double_induction2
|
||||
{A : Type} {x y z : A} (p : x ≈ y) (q : z ≈ y)
|
||||
{C : Π(x y z : A), Π(p : x ≈ y), Π(q : z ≈ y), Type}
|
||||
(H : C z z z (idpath z) (idpath z)) :
|
||||
C x y z p q :=
|
||||
induction_on p (take y q, induction_on q H) y q
|
||||
|
||||
theorem double_induction2'
|
||||
{A : Type} {x y z : A} (p : x ≈ y) (q : z ≈ y)
|
||||
{C : Π(x y z : A), Π(p : x ≈ y), Π(q : z ≈ y), Type}
|
||||
(H : C z z z (idpath z) (idpath z)) : C x y z p q :=
|
||||
induction_on p (take y q, induction_on q H) y q
|
||||
|
||||
theorem triple_induction
|
||||
{A : Type} {x y z w : A} (p : x ≈ y) (q : y ≈ z) (r : z ≈ w)
|
||||
{C : Π(x y z w : A), Π(p : x ≈ y), Π(q : y ≈ z), Π(r: z ≈ w), Type}
|
||||
(H : C x x x x (idpath x) (idpath x) (idpath x)) :
|
||||
C x y z w p q r :=
|
||||
induction_on p (take z q, induction_on q (take w r, induction_on r H)) z q w r
|
||||
|
||||
-- try this again
|
||||
definition concat_pV_p_new {A : Type} {x y z : A} (p : x ≈ z) (q : y ≈ z) : (p @ q^) @ q ≈ p :=
|
||||
double_induction2 p q idp
|
||||
|
||||
-- old proof:
|
||||
-- induction_on q (take p, induction_on p idp) p
|
||||
|
||||
-- This is an attempt to do it as a tactic proof
|
||||
-- proof
|
||||
-- apply (induction_on q _ p),
|
||||
-- take p,
|
||||
-- apply (induction_on p idp)
|
||||
-- qed
|
||||
|
||||
-- set_option unifier.max_steps 1000000
|
||||
|
||||
-- TODO: update: this no longer works, but it used to (it took a couple of seconds)
|
||||
|
||||
-- theorem test {A : Type} (P : A → Type) (x : A) (u_1 : P x) :
|
||||
-- path
|
||||
-- (concat
|
||||
-- (concat (ap (λ (e : path x x), transport P e u_1) (concat_p_pp (idpath x) (idpath x) (idpath x)))
|
||||
-- (transport_pp P (concat (idpath x) (idpath x)) (idpath x) u_1))
|
||||
-- (ap (transport P (idpath x)) (transport_pp P (idpath x) (idpath x) u_1)))
|
||||
-- (concat (transport_pp P (idpath x) (concat (idpath x) (idpath x)) u_1)
|
||||
-- (transport_pp P (idpath x) (idpath x) (transport P (idpath x) u_1))) :=
|
||||
-- idp
|
||||
|
||||
-- definition transport_p_pp {A : Type} (P : A → Type)
|
||||
-- {x y z w : A} (p : x ≈ y) (q : y ≈ z) (r : z ≈ w) (u : P x) :
|
||||
-- ap (λe, e # u) (concat_p_pp p q r) @ (transport_pp P (p @ q) r u) @
|
||||
-- ap (transport P r) (transport_pp P p q u)
|
||||
-- ≈ (transport_pp P p (q @ r) u) @ (transport_pp P q r (p # u))
|
||||
-- :> ((p @ (q @ r)) # u ≈ r # q # p # u) :=
|
||||
-- triple_induction p q r _ u
|
||||
-- triple_induction p q r (take u, test P x u) u
|
||||
|
||||
-- this doesn't work, even with max_steps = 100000
|
||||
--double_induction p q (take r, induction_on r (take u, test P x u))) r u
|
||||
|
||||
-- even this doesn't work!
|
||||
-- definition transport_p_pp' {A : Type} (P : A → Type)
|
||||
-- {x y z w : A} (p : x ≈ y) (q : y ≈ z) (r : z ≈ w) (u : P x) :
|
||||
-- ap (λe, e # u) (concat_p_pp p q r) @ (transport_pp P (p @ q) r u) @
|
||||
-- ap (transport P r) (transport_pp P p q u)
|
||||
-- ≈ (transport_pp P p (q @ r) u) @ (transport_pp P q r (p # u))
|
||||
-- :> ((p @ (q @ r)) # u ≈ r # q # p # u) :=
|
||||
-- have aux:
|
||||
-- Πu_1 : P x, path
|
||||
-- (concat
|
||||
-- (concat (ap (λ (e : path x x), transport' e u_1) (concat_p_pp (idpath x) (idpath x) (idpath x)))
|
||||
-- (transport_pp P (concat (idpath x) (idpath x)) (idpath x) u_1))
|
||||
-- (ap (transport P (idpath x)) (transport_pp P (idpath x) (idpath x) u_1)))
|
||||
-- (concat (transport_pp P (idpath x) (concat (idpath x) (idpath x)) u_1)
|
||||
-- (transport_pp P (idpath x) (idpath x) (transport' (idpath x) u_1))), from take u_1, idp,
|
||||
-- triple_induction p q r (take u, aux u) u
|
||||
|
||||
-- This works with max_steps = 10000
|
||||
-- definition transport_p_pp {A : Type} (P : A → Type)
|
||||
-- {x y z w : A} (p : x ≈ y) (q : y ≈ z) (r : z ≈ w) (u : P x) :
|
||||
-- ap (λe, e # u) (concat_p_pp p q r) @ (transport_pp P (p @ q) r u) @
|
||||
-- ap (transport P r) (transport_pp P p q u)
|
||||
-- ≈ (transport_pp P p (q @ r) u) @ (transport_pp P q r (p # u))
|
||||
-- :> ((p @ (q @ r)) # u ≈ r # q # p # u) :=
|
||||
-- induction_on p (take q, induction_on q (take r, induction_on r (take u, test P x u))) q r u
|
||||
|
||||
-- This shows the goal, with max_steps = 100000
|
||||
-- definition transport_p_pp {A : Type} (P : A → Type)
|
||||
-- {x y z w : A} (p : x ≈ y) (q : y ≈ z) (r : z ≈ w) (u : P x) :
|
||||
-- ap (λe, e # u) (concat_p_pp p q r) @ (transport_pp P (p @ q) r u) @
|
||||
-- ap (transport P r) (transport_pp P p q u)
|
||||
-- ≈ (transport_pp P p (q @ r) u) @ (transport_pp P q r (p # u))
|
||||
-- :> ((p @ (q @ r)) # u ≈ r # q # p # u) :=
|
||||
-- induction_on p (take q, induction_on q (take r, induction_on r (take u, _)))) q r u
|
||||
|
||||
|
||||
|
||||
-- Back to the regular development
|
||||
|
||||
-- In the future, we may expect to need some higher coherence for transport:
|
||||
-- for instance, that transport acting on the associator is trivial.
|
||||
|
||||
-- set_option unifier.max_steps 1000000
|
||||
|
||||
-- TODO: we cannot get this yet
|
||||
-- in Coq, the type annotation is only for clarity -- it is not needed
|
||||
definition transport_p_pp {A : Type} (P : A → Type)
|
||||
{x y z w : A} (p : x ≈ y) (q : y ≈ z) (r : z ≈ w) (u : P x) :
|
||||
ap (λe, e # u) (concat_p_pp p q r) @ (transport_pp P (p @ q) r u) @
|
||||
ap (transport P r) (transport_pp P p q u)
|
||||
≈ (transport_pp P p (q @ r) u) @ (transport_pp P q r (p # u))
|
||||
:> ((p @ (q @ r)) # u ≈ r # q # p # u) :=
|
||||
sorry
|
||||
|
||||
(-- Coq proof:
|
||||
Proof.
|
||||
destruct p, q, r. simpl. exact 1.
|
||||
Defined.
|
||||
--)
|
||||
|
||||
-- Here is another coherence lemma for transport.
|
||||
definition transport_pVp {A} (P : A → Type) {x y : A} (p : x ≈ y) (z : P x) :
|
||||
transport_pV P p (transport P p z) ≈ ap (transport P p) (transport_Vp P p z)
|
||||
:= induction_on p idp
|
||||
|
||||
-- Dependent transport in a doubly dependent type.
|
||||
definition transportD {A : Type} (B : A → Type) (C : Π a : A, B a → Type)
|
||||
{x1 x2 : A} (p : x1 ≈ x2) (y : B x1) (z : C x1 y) :
|
||||
C x2 (p # y) :=
|
||||
induction_on p z
|
||||
|
||||
-- Transporting along higher-dimensional paths
|
||||
definition transport2 {A : Type} (P : A → Type) {x y : A} {p q : x ≈ y} (r : p ≈ q) (z : P x) :
|
||||
p # z ≈ q # z := ap (λp', p' # z) r
|
||||
|
||||
-- An alternative definition.
|
||||
definition transport2_is_ap10 {A : Type} (Q : A → Type) {x y : A} {p q : x ≈ y} (r : p ≈ q)
|
||||
(z : Q x) :
|
||||
transport2 Q r z ≈ ap10 (ap (transport Q) r) z :=
|
||||
induction_on r idp
|
||||
|
||||
definition transport2_p2p {A : Type} (P : A → Type) {x y : A} {p1 p2 p3 : x ≈ y}
|
||||
(r1 : p1 ≈ p2) (r2 : p2 ≈ p3) (z : P x) :
|
||||
transport2 P (r1 @ r2) z ≈ transport2 P r1 z @ transport2 P r2 z :=
|
||||
induction_on r1 (induction_on r2 idp)
|
||||
|
||||
definition transport2_V {A : Type} (Q : A → Type) {x y : A} {p q : x ≈ y} (r : p ≈ q) (z : Q x) :
|
||||
transport2 Q (r^) z ≈ ((transport2 Q r z)^) :=
|
||||
induction_on r idp
|
||||
|
||||
definition concat_AT {A : Type} (P : A → Type) {x y : A} {p q : x ≈ y} {z w : P x} (r : p ≈ q)
|
||||
(s : z ≈ w) :
|
||||
ap (transport P p) s @ transport2 P r w ≈ transport2 P r z @ ap (transport P q) s :=
|
||||
induction_on r (concat_p1 _ @ (concat_1p _)^)
|
||||
|
||||
-- TODO (from Coq library): What should this be called?
|
||||
definition ap_transport {A} {P Q : A → Type} {x y : A} (p : x ≈ y) (f : Πx, P x → Q x) (z : P x) :
|
||||
f y (p # z) ≈ (p # (f x z)) :=
|
||||
induction_on p idp
|
||||
|
||||
|
||||
-- Transporting in particular fibrations
|
||||
-- -------------------------------------
|
||||
|
||||
(-- From the Coq HoTT library:
|
||||
|
||||
One frequently needs lemmas showing that transport in a certain dependent type is equal to some
|
||||
more explicitly defined operation, defined according to the structure of that dependent type.
|
||||
For most dependent types, we prove these lemmas in the appropriate file in the types/
|
||||
subdirectory. Here we consider only the most basic cases.
|
||||
|
||||
--)
|
||||
|
||||
-- Transporting in a constant fibration.
|
||||
definition transport_const {A B : Type} {x1 x2 : A} (p : x1 ≈ x2) (y : B) :
|
||||
transport (λx, B) p y ≈ y :=
|
||||
induction_on p idp
|
||||
|
||||
definition transport2_const {A B : Type} {x1 x2 : A} {p q : x1 ≈ x2} (r : p ≈ q) (y : B) :
|
||||
transport_const p y ≈ transport2 (λu, B) r y @ transport_const q y :=
|
||||
induction_on r (concat_1p _)^
|
||||
|
||||
-- Transporting in a pulled back fibration.
|
||||
definition transport_compose {A B} {x y : A} (P : B → Type) (f : A → B) (p : x ≈ y) (z : P (f x)) :
|
||||
transport (λx, P (f x)) p z ≈ transport P (ap f p) z :=
|
||||
induction_on p idp
|
||||
|
||||
definition transport_precompose {A B C} (f : A → B) (g g' : B → C) (p : g ≈ g') :
|
||||
transport (λh : B → C, g ∘ f ≈ h ∘ f) p idp ≈ ap (λh, h ∘ f) p :=
|
||||
induction_on p idp
|
||||
|
||||
definition apD10_ap_precompose {A B C} (f : A → B) (g g' : B → C) (p : g ≈ g') (a : A) :
|
||||
apD10 (ap (λh : B → C, h ∘ f) p) a ≈ apD10 p (f a) :=
|
||||
induction_on p idp
|
||||
|
||||
definition apD10_ap_postcompose {A B C} (f : B → C) (g g' : A → B) (p : g ≈ g') (a : A) :
|
||||
apD10 (ap (λh : A → B, f ∘ h) p) a ≈ ap f (apD10 p a) :=
|
||||
induction_on p idp
|
||||
|
||||
-- A special case of [transport_compose] which seems to come up a lot.
|
||||
definition transport_idmap_ap A (P : A → Type) x y (p : x ≈ y) (u : P x) :
|
||||
transport P p u ≈ transport (λz, z) (ap P p) u :=
|
||||
induction_on p idp
|
||||
|
||||
|
||||
-- The behavior of [ap] and [apD]
|
||||
-- ------------------------------
|
||||
|
||||
-- In a constant fibration, [apD] reduces to [ap], modulo [transport_const].
|
||||
definition apD_const {A B} {x y : A} (f : A → B) (p: x ≈ y) :
|
||||
apD f p ≈ transport_const p (f x) @ ap f p :=
|
||||
induction_on p idp
|
||||
|
||||
|
||||
-- The 2-dimensional groupoid structure
|
||||
-- ------------------------------------
|
||||
|
||||
-- Horizontal composition of 2-dimensional paths.
|
||||
definition concat2 {A} {x y z : A} {p p' : x ≈ y} {q q' : y ≈ z} (h : p ≈ p') (h' : q ≈ q') :
|
||||
p @ q ≈ p' @ q' :=
|
||||
induction_on h (induction_on h' idp)
|
||||
|
||||
infixl `@@`:75 := concat2
|
||||
|
||||
-- 2-dimensional path inversion
|
||||
definition inverse2 {A : Type} {x y : A} {p q : x ≈ y} (h : p ≈ q) : p^ ≈ q^ :=
|
||||
induction_on h idp
|
||||
|
||||
|
||||
-- Whiskering
|
||||
-- ----------
|
||||
|
||||
definition whiskerL {A : Type} {x y z : A} (p : x ≈ y) {q r : y ≈ z} (h : q ≈ r) : p @ q ≈ p @ r :=
|
||||
idp @@ h
|
||||
|
||||
definition whiskerR {A : Type} {x y z : A} {p q : x ≈ y} (h : p ≈ q) (r : y ≈ z) : p @ r ≈ q @ r :=
|
||||
h @@ idp
|
||||
|
||||
-- Unwhiskering, a.k.a. cancelling
|
||||
|
||||
definition cancelL {A} {x y z : A} (p : x ≈ y) (q r : y ≈ z) : (p @ q ≈ p @ r) → (q ≈ r) :=
|
||||
induction_on p (take r, induction_on r (take q a, (concat_1p q)^ @ a)) r q
|
||||
|
||||
definition cancelR {A} {x y z : A} (p q : x ≈ y) (r : y ≈ z) : (p @ r ≈ q @ r) → (p ≈ q) :=
|
||||
induction_on r (take p, induction_on p (take q a, a @ concat_p1 q)) p q
|
||||
|
||||
-- Whiskering and identity paths.
|
||||
|
||||
definition whiskerR_p1 {A : Type} {x y : A} {p q : x ≈ y} (h : p ≈ q) :
|
||||
(concat_p1 p)^ @ whiskerR h idp @ concat_p1 q ≈ h :=
|
||||
induction_on h (induction_on p idp)
|
||||
|
||||
definition whiskerR_1p {A : Type} {x y z : A} (p : x ≈ y) (q : y ≈ z) :
|
||||
whiskerR idp q ≈ idp :> (p @ q ≈ p @ q) :=
|
||||
induction_on q idp
|
||||
|
||||
definition whiskerL_p1 {A : Type} {x y z : A} (p : x ≈ y) (q : y ≈ z) :
|
||||
whiskerL p idp ≈ idp :> (p @ q ≈ p @ q) :=
|
||||
induction_on q idp
|
||||
|
||||
definition whiskerL_1p {A : Type} {x y : A} {p q : x ≈ y} (h : p ≈ q) :
|
||||
(concat_1p p) ^ @ whiskerL idp h @ concat_1p q ≈ h :=
|
||||
induction_on h (induction_on p idp)
|
||||
|
||||
definition concat2_p1 {A : Type} {x y : A} {p q : x ≈ y} (h : p ≈ q) :
|
||||
h @@ idp ≈ whiskerR h idp :> (p @ idp ≈ q @ idp) :=
|
||||
induction_on h idp
|
||||
|
||||
definition concat2_1p {A : Type} {x y : A} {p q : x ≈ y} (h : p ≈ q) :
|
||||
idp @@ h ≈ whiskerL idp h :> (idp @ p ≈ idp @ q) :=
|
||||
induction_on h idp
|
||||
|
||||
-- TODO: note, 4 inductions
|
||||
-- The interchange law for concatenation.
|
||||
definition concat_concat2 {A : Type} {x y z : A} {p p' p'' : x ≈ y} {q q' q'' : y ≈ z}
|
||||
(a : p ≈ p') (b : p' ≈ p'') (c : q ≈ q') (d : q' ≈ q'') :
|
||||
(a @@ c) @ (b @@ d) ≈ (a @ b) @@ (c @ d) :=
|
||||
induction_on d (induction_on c (induction_on b (induction_on a idp)))
|
||||
|
||||
definition concat_whisker {A} {x y z : A} (p p' : x ≈ y) (q q' : y ≈ z) (a : p ≈ p') (b : q ≈ q') :
|
||||
(whiskerR a q) @ (whiskerL p' b) ≈ (whiskerL p b) @ (whiskerR a q') :=
|
||||
induction_on b (induction_on a (concat_1p _)^)
|
||||
|
||||
-- Structure corresponding to the coherence equations of a bicategory.
|
||||
|
||||
-- The "pentagonator": the 3-cell witnessing the associativity pentagon.
|
||||
definition pentagon {A : Type} {v w x y z : A} (p : v ≈ w) (q : w ≈ x) (r : x ≈ y) (s : y ≈ z) :
|
||||
whiskerL p (concat_p_pp q r s)
|
||||
@ concat_p_pp p (q @ r) s
|
||||
@ whiskerR (concat_p_pp p q r) s
|
||||
≈ concat_p_pp p q (r @ s) @ concat_p_pp (p @ q) r s :=
|
||||
sorry
|
||||
-- induction_on p (induction_on q (induction_on r (induction_on s idp)))
|
||||
|
||||
(-- The Coq proof:
|
||||
|
||||
-- The "pentagonator": the 3-cell witnessing the associativity pentagon.
|
||||
definition pentagon {A : Type} {v w x y z : A} (p : v ≈ w) (q : w ≈ x) (r : x ≈ y) (s : y ≈ z)
|
||||
: whiskerL p (concat_p_pp q r s)
|
||||
@ concat_p_pp p (q@r) s
|
||||
@ whiskerR (concat_p_pp p q r) s
|
||||
≈ concat_p_pp p q (r@s) @ concat_p_pp (p@q) r s.
|
||||
Proof.
|
||||
case p, q, r, s. reflexivity.
|
||||
Defined.
|
||||
|
||||
--)
|
||||
|
||||
-- The 3-cell witnessing the left unit triangle.
|
||||
definition triangulator {A : Type} {x y z : A} (p : x ≈ y) (q : y ≈ z) :
|
||||
concat_p_pp p idp q @ whiskerR (concat_p1 p) q ≈ whiskerL p (concat_1p q) :=
|
||||
induction_on p (take q, induction_on q idp) q
|
||||
|
||||
definition eckmann_hilton {A : Type} {x:A} (p q : idp ≈ idp :> (x ≈ x)) : p @ q ≈ q @ p :=
|
||||
(whiskerR_p1 p @@ whiskerL_1p q)^
|
||||
@ (concat_p1 _ @@ concat_p1 _)
|
||||
@ (concat_1p _ @@ concat_1p _)
|
||||
@ (concat_whisker _ _ _ _ p q)
|
||||
@ (concat_1p _ @@ concat_1p _)^
|
||||
@ (concat_p1 _ @@ concat_p1 _)^
|
||||
@ (whiskerL_1p q @@ whiskerR_p1 p)
|
||||
|
||||
|
||||
-- The action of functions on 2-dimensional paths
|
||||
definition ap02 {A B : Type} (f:A → B) {x y : A} {p q : x ≈ y} (r : p ≈ q) : ap f p ≈ ap f q :=
|
||||
induction_on r idp
|
||||
|
||||
definition ap02_pp {A B} (f : A → B) {x y : A} {p p' p'' : x ≈ y} (r : p ≈ p') (r' : p' ≈ p'') :
|
||||
ap02 f (r @ r') ≈ ap02 f r @ ap02 f r' :=
|
||||
induction_on r (induction_on r' idp)
|
||||
|
||||
definition ap02_p2p {A B} (f : A → B) {x y z : A} {p p' : x ≈ y} {q q' :y ≈ z} (r : p ≈ p')
|
||||
(s : q ≈ q') :
|
||||
ap02 f (r @@ s) ≈ ap_pp f p q
|
||||
@ (ap02 f r @@ ap02 f s)
|
||||
@ (ap_pp f p' q')^ :=
|
||||
sorry
|
||||
-- induction_on r (induction_on s (induction_on p (induction_on q idp)))
|
||||
|
||||
definition apD02 {A : Type} {B : A → Type} {x y : A} {p q : x ≈ y} (f : Π x, B x) (r : p ≈ q) :
|
||||
apD f p ≈ transport2 B r (f x) @ apD f q :=
|
||||
induction_on r (concat_1p _)^
|
||||
|
||||
-- And now for a lemma whose statement is much longer than its proof.
|
||||
definition apD02_pp {A} (B : A → Type) (f : Π x:A, B x) {x y : A}
|
||||
{p1 p2 p3 : x ≈ y} (r1 : p1 ≈ p2) (r2 : p2 ≈ p3) :
|
||||
apD02 f (r1 @ r2) ≈ apD02 f r1
|
||||
@ whiskerL (transport2 B r1 (f x)) (apD02 f r2)
|
||||
@ concat_p_pp _ _ _
|
||||
@ (whiskerR ((transport2_p2p B r1 r2 (f x))^) (apD f p3)) :=
|
||||
sorry
|
||||
-- induction_on r1 (take r2, induction_on r2 (take p1, induction_on p1 idp)) r2 p1
|
||||
|
||||
(--
|
||||
|
||||
The Coq proof:
|
||||
definition apD02_pp {A} (B : A → Type) (f : Π x:A, B x) {x y : A}
|
||||
{p1 p2 p3 : x ≈ y} (r1 : p1 ≈ p2) (r2 : p2 ≈ p3)
|
||||
: apD02 f (r1 @ r2)
|
||||
≈ apD02 f r1
|
||||
@ whiskerL (transport2 B r1 (f x)) (apD02 f r2)
|
||||
@ concat_p_pp _ _ _
|
||||
@ (whiskerR (transport2_p2p B r1 r2 (f x))^ (apD f p3)).
|
||||
Proof.
|
||||
destruct r1, r2. destruct p1. reflexivity.
|
||||
Defined.
|
||||
|
||||
--)
|
||||
|
||||
(--
|
||||
-- ** Tactics, hints, and aliases
|
||||
|
||||
-- [concat], with arguments flipped. Useful mainly in the idiom [apply (concatR (expression))]. Given as a notation not a definition so that the resultant terms are literally instances of [concat], with no unfolding required.
|
||||
Notation concatR := (λp q, concat q p).
|
||||
|
||||
Hint Resolve
|
||||
concat_1p concat_p1 concat_p_pp
|
||||
inv_pp inv_V
|
||||
: path_hints.
|
||||
|
||||
(* First try at a paths db
|
||||
We want the RHS of the equation to become strictly simpler
|
||||
Hint Rewrite
|
||||
@concat_p1
|
||||
@concat_1p
|
||||
@concat_p_pp (* there is a choice here !*)
|
||||
@concat_pV
|
||||
@concat_Vp
|
||||
@concat_V_pp
|
||||
@concat_p_Vp
|
||||
@concat_pp_V
|
||||
@concat_pV_p
|
||||
(*@inv_pp*) (* I am not sure about this one
|
||||
@inv_V
|
||||
@moveR_Mp
|
||||
@moveR_pM
|
||||
@moveL_Mp
|
||||
@moveL_pM
|
||||
@moveL_1M
|
||||
@moveL_M1
|
||||
@moveR_M1
|
||||
@moveR_1M
|
||||
@ap_1
|
||||
(* @ap_pp
|
||||
@ap_p_pp ?*)
|
||||
@inverse_ap
|
||||
@ap_idmap
|
||||
(* @ap_compose
|
||||
@ap_compose'*)
|
||||
@ap_const
|
||||
(* Unsure about naturality of [ap], was absent in the old implementation*)
|
||||
@apD10_1
|
||||
:paths.
|
||||
|
||||
Ltac hott_simpl :=
|
||||
autorewrite with paths in * |- * ; auto with path_hints.
|
||||
|
||||
--)
|
Loading…
Reference in a new issue