(************************************************************************)
(*         *      The Rocq Prover / The Rocq Development Team           *)
(*  v      *         Copyright INRIA, CNRS and contributors             *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)
(* Created by Bruno Barras, Jan 1998 *)
(* Made a module instance for EqdepFacts by Hugo Herbelin, Mar 2006 *)
(** We prove that there is only one proof of [x=x], i.e [eq_refl x]. This holds if the equality upon the set of [x] is decidable. A corollary of this theorem is the equality of the right projections of two equal dependent pairs.  Author:   Thomas Kleymann |<tms@dcs.ed.ac.uk>| in Lego adapted to Coq by B. Barras  Credit:   Proofs up to [K_dec] follow an outline by Michael Hedberg  Table of contents:  1. Streicher's K and injectivity of dependent pair hold on decidable types  1.1. Definition of the functor that builds properties of dependent equalities from a proof of decidability of equality for a set in Type  1.2. Definition of the functor that builds properties of dependent equalities from a proof of decidability of equality for a set in Set  *)
(************************************************************************)
(** * Streicher's K and injectivity of dependent pair hold on decidable types *)
Set Implicit Arguments.
(* Set Universe Polymorphism. *)
Section EqdepDec.
Variable A : Type.
Let comp (x y y':A) (eq1:x = y) (eq2:x = y') : y = y' :=
eq_ind _ (fun a => a = y') eq2 _ eq1.
Remark trans_sym_eq (x y:A) (u:x = y) : comp u u = eq_refl y.
Variable x : A.
Variable eq_dec : forall y:A, x = y \/ x <> y.
Let nu (y:A) (u:x = y) : x = y :=
match eq_dec y with
| or_introl eqxy => eqxy
| or_intror neqxy => False_ind _ (neqxy u)
end.
Local Lemma nu_constant (y:A) (u v:x = y) : nu u = nu v.
Let nu_inv (y:A) (v:x = y) : x = y := comp (nu (eq_refl x)) v.
Remark nu_left_inv_on (y:A) (u:x = y) : nu_inv (nu u) = u.

Theorem K_dec_on (P:x = x -> Prop) (H:P (eq_refl x)) (p:x = x) : P p.
Let proj (P:A -> Prop) (exP:ex P) (def:P x) : P x :=
match exP with
| ex_intro _ x' prf =>
match eq_dec x' with
| or_introl eqprf => eq_ind x' P prf x (eq_sym eqprf)
| _ => def
end
end.