2015-02-13 20:40:55 +00:00
/-
Copyright (c) 2014 Floris van Doorn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Floris van Doorn
Ported from Coq HoTT
Theorems about pi-types (dependent function spaces)
-/
import types.sigma
open eq equiv is_equiv funext
namespace pi
universe variables l k
variables {A A' : Type.{l}} {B : A → Type.{k}} {B' : A' → Type.{k}} {C : Πa, B a → Type}
{D : Πa b, C a b → Type}
{a a' a'' : A} {b b₁ b₂ : B a} {b' : B a'} {b'' : B a''} {f g : Πa, B a}
/- Paths -/
/- Paths [p : f ≈ g] in a function type [Πx:X, P x] are equivalent to functions taking values in path types, [H : Πx:X, f x ≈ g x], or concisely, [H : f ∼ g].
This equivalence, however, is just the combination of [apD10] and function extensionality [funext], and as such, [path_forall], et seq. are given in axioms.funext and path: -/
/- Now we show how these things compute. -/
2015-06-26 02:55:05 +00:00
definition apd10_path_pi (H : funext) (h : f ~ g) : apd10 (eq_of_homotopy h) ~ h :=
2015-04-29 17:15:13 +00:00
apd10 (right_inv apd10 h)
2015-02-13 20:40:55 +00:00
2015-04-29 17:15:13 +00:00
definition path_pi_eta (H : funext) (p : f = g) : eq_of_homotopy (apd10 p) = p :=
left_inv apd10 p
2015-02-13 20:40:55 +00:00
2015-02-26 18:51:19 +00:00
print classes
definition path_pi_idp (H : funext) : eq_of_homotopy (λx : A, refl (f x)) = refl f :=
path_pi_eta H _
2015-02-13 20:40:55 +00:00
/- The identification of the path space of a dependent function space, up to equivalence, is of course just funext. -/
2015-06-26 02:55:05 +00:00
definition path_equiv_homotopy (H : funext) (f g : Πx, B x) : (f = g) ≃ (f ~ g) :=
2016-03-19 14:38:05 +00:00
equiv.mk _ !is_equiv_apdt
2015-02-13 20:40:55 +00:00
2015-02-26 18:51:19 +00:00
definition is_equiv_path_pi [instance] (H : funext) (f g : Πx, B x)
: is_equiv (@eq_of_homotopy _ _ f g) :=
2015-04-29 17:15:13 +00:00
is_equiv_inv apd10
2015-02-13 20:40:55 +00:00
2015-06-26 02:55:05 +00:00
definition homotopy_equiv_path (H : funext) (f g : Πx, B x) : (f ~ g) ≃ (f = g) :=
2015-02-26 18:51:19 +00:00
equiv.mk _ (is_equiv_path_pi H f g)
2015-02-13 20:40:55 +00:00
/- Transport -/
protected definition transport (p : a = a') (f : Π(b : B a), C a b)
: (transport (λa, Π(b : B a), C a b) p f)
2015-06-26 02:55:05 +00:00
~ (λb, transport (C a') !tr_inv_tr (transportD _ p _ (f (p⁻¹ ▸ b)))) :=
2015-02-13 20:40:55 +00:00
eq.rec_on p (λx, idp)
/- A special case of [transport_pi] where the type [B] does not depend on [A],
and so it is just a fixed type [B]. -/
definition transport_constant {C : A → A' → Type} (p : a = a') (f : Π(b : A'), C a b)
2015-06-26 02:55:05 +00:00
: (eq.transport (λa, Π(b : A'), C a b) p f) ~ (λb, eq.transport (λa, C a b) p (f b)) :=
2015-02-13 20:40:55 +00:00
eq.rec_on p (λx, idp)
/- Maps on paths -/
/- The action of maps given by lambda. -/
2015-02-26 18:51:19 +00:00
definition ap_lambdaD (H : funext) {C : A' → Type} (p : a = a') (f : Πa b, C b) :
2015-02-22 17:39:27 +00:00
ap (λa b, f a b) p = eq_of_homotopy (λb, ap (λa, f a b) p) :=
2015-02-13 20:40:55 +00:00
begin
apply (eq.rec_on p),
apply inverse,
2015-02-26 18:51:19 +00:00
apply (path_pi_idp H)
2015-02-13 20:40:55 +00:00
end
/- Dependent paths -/
/- with more implicit arguments the conclusion of the following theorem is
(Π(b : B a), transportD B C p b (f b) = g (eq.transport B p b)) ≃
(eq.transport (λa, Π(b : B a), C a b) p f = g) -/
2015-02-26 18:51:19 +00:00
definition dpath_pi (H : funext) (p : a = a') (f : Π(b : B a), C a b) (g : Π(b' : B a'), C a' b')
2015-05-07 23:20:20 +00:00
: (Π(b : B a), p ▸D (f b) = g (p ▸ b)) ≃ (p ▸ f = g) :=
2015-02-26 18:51:19 +00:00
eq.rec_on p (λg, homotopy_equiv_path H f g) g
2015-02-13 20:40:55 +00:00
section open sigma sigma.ops
/- more implicit arguments:
2015-05-07 23:20:20 +00:00
(Π(b : B a), eq.transport C (sigma.path p idp) (f b) = g (p ▸ b)) ≃
2015-02-13 20:40:55 +00:00
(Π(b : B a), transportD B (λ(a : A) (b : B a), C ⟨a, b⟩) p b (f b) = g (eq.transport B p b)) -/
definition dpath_pi_sigma {C : (Σa, B a) → Type} (p : a = a')
(f : Π(b : B a), C ⟨a, b⟩) (g : Π(b' : B a'), C ⟨a', b'⟩) :
2015-05-27 01:17:46 +00:00
(Π(b : B a), (sigma.sigma_eq p !pathover_tr) ▸ (f b) = g (p ▸ b)) ≃ (Π(b : B a), p ▸D (f b) = g (p ▸ b)) :=
2015-02-13 20:40:55 +00:00
eq.rec_on p (λg, !equiv.refl) g
end
variables (f0 : A' → A) (f1 : Π(a':A'), B (f0 a') → B' a')
definition transport_V [reducible] (P : A → Type) {x y : A} (p : x = y) (u : P y) : P x :=
2015-05-07 23:20:20 +00:00
p⁻¹ ▸ u
2015-02-13 20:40:55 +00:00
2015-05-19 05:35:18 +00:00
definition functor_pi : (Π(a:A), B a) → (Π(a':A'), B' a') := (λg a', f1 a' (g (f0 a')))
2015-02-13 20:40:55 +00:00
/- Equivalences -/
definition isequiv_functor_pi [instance] (f0 : A' → A) (f1 : Π(a':A'), B (f0 a') → B' a')
[H0 : is_equiv f0] [H1 : Πa', @is_equiv (B (f0 a')) (B' a') (f1 a')]
: is_equiv (functor_pi f0 f1) :=
begin
apply (adjointify (functor_pi f0 f1) (functor_pi (f0⁻¹)
2015-04-29 17:15:13 +00:00
(λ(a : A) (b' : B' (f0⁻¹ a)), transport B (right_inv f0 a) ((f1 (f0⁻¹ a))⁻¹ b')))),
2015-02-22 17:39:27 +00:00
intro h, apply eq_of_homotopy,
2015-03-28 00:26:06 +00:00
esimp [functor_pi, function.compose], -- simplify (and unfold function_pi and function.compose)
2015-02-13 20:40:55 +00:00
--first subgoal
intro a', esimp,
rewrite adj,
2015-08-06 21:50:57 +00:00
rewrite -tr_compose,
2015-02-22 17:39:27 +00:00
rewrite {f1 a' _}(fn_tr_eq_tr_fn _ f1 _),
2015-04-29 17:15:13 +00:00
rewrite (right_inv (f1 _) _),
2016-03-19 14:38:05 +00:00
apply apdt,
2015-07-29 12:17:16 +00:00
intro h,
2015-02-22 17:39:27 +00:00
apply eq_of_homotopy, intro a, esimp,
2015-05-07 23:20:20 +00:00
apply (transport_V (λx, right_inv f0 a ▸ x = h a) (left_inv (f1 _) _)),
2016-03-19 14:38:05 +00:00
apply apdt
2015-02-13 20:40:55 +00:00
end
end pi