Section Dependent_Equality.
Variable U : Type.
Variable P : U -> Type.
(** Dependent equality *)
Inductive eq_dep (p:U) (x:P p) : forall q:U, P q -> Prop :=
eq_dep_intro : eq_dep p x p x.
Hint Constructors eq_dep: core.
Proof eq_dep_intro.
Hint Immediate eq_dep_sym: core.
Scheme eq_indd := Induction for eq Sort Prop.
(** Equivalent definition of dependent equality as a dependent pair of equalities *)
Inductive eq_dep1 (p:U) (x:P p) (q:U) (y:P q) : Prop :=
eq_dep1_intro : forall h:q = p, x = rew h in y -> eq_dep1 p x q y.
End Dependent_Equality.
Arguments eq_dep  [U P] p x q _.
Arguments eq_dep1 [U P] p x q y.
(** Dependent equality is equivalent to equality on dependent pairs *)
Notation equiv_eqex_eqdep := eq_sigT_iff_eq_dep (only parsing). (* Compat *)
(** Dependent equality is equivalent to a dependent pair of equalities *)
Set Implicit Arguments.
Proof (fun eq_rect_eq P p y x =>
@eq_rect_eq_on__eq_dep1_eq_on p P x (eq_rect_eq p P x) y).
Proof (fun eq_rect_eq P p x y =>
@eq_rect_eq_on__eq_dep_eq_on p P x (eq_rect_eq p P x) y).
(** Uniqueness of Identity Proofs (UIP) is a consequence of *)
(** Injectivity of Dependent Equality *)
Proof (fun eq_dep_eq x y p1 =>
@eq_dep_eq_on__UIP_on x y p1 (eq_dep_eq _ _ _)).
(** Uniqueness of Reflexive Identity Proofs is a direct instance of UIP *)
Proof (fun UIP x p =>
@UIP_on__UIP_refl_on x (UIP x x eq_refl) p).
(** Streicher's axiom K is a direct consequence of Uniqueness of Reflexive Identity Proofs *)
Proof (fun UIP_refl x P =>
@UIP_refl_on__Streicher_K_on x P (UIP_refl x)).
(** We finally recover from K the Invariance by Substitution of Reflexive Equality Proofs *)
Proof (fun Streicher_K p P x =>
@Streicher_K_on__eq_rect_eq_on p P x (Streicher_K p _)).
(** Remark: It is reasonable to think that [eq_rect_eq] is strictly stronger than [eq_rec_eq] (which is [eq_rect_eq] restricted on [Set]):  [Definition Eq_rec_eq := forall (P:U -> Set) (p:U) (x:P p) (h:p = p), x = eq_rec p P x p h.]  Typically, [eq_rect_eq] allows proving UIP and Streicher's K what does not seem possible with [eq_rec_eq]. In particular, the proof of [UIP] requires to use [eq_rect_eq] on [fun y -> x=y] which is in [Type] but not in [Set]. *)
End Equivalences.
(** UIP_refl is downward closed (a short proof of the key lemma of Voevodsky's proof of inclusion of h-level n into h-level n+1; see hlevelntosn in https://github.com/vladimirias/Foundations.git). *)

Theorem UIP_shift_on (X : Type) (x : X) :
UIP_refl_on_ X x -> forall y : x = x, UIP_refl_on_ (x = x) y.