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 : forall (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.
Let nu_constant : forall (y:A) (u v:x = y), nu u = nu v.
intros.
unfold nu.
destruct (eq_dec y) as [Heq|Hneq].
- reflexivity.
- case Hneq; trivial.
Qed.
Let nu_inv (y:A) (v:x = y) : x = y := comp (nu (eq_refl x)) v.
Remark nu_left_inv_on : forall (y:A) (u:x = y), nu_inv (nu u) = u.
(** The corollary *)
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.
End EqdepDec.
(** Now we prove the versions that require decidable equality for the entire type rather than just on the given element.  The rest of the file uses this total decidable equality.  We could do everything using decidable equality at a point (because the induction rule for [eq] is really an induction rule for [{ y : A | x = y }]), but we don't currently, because changing everything would break backward compatibility and no-one has yet taken the time to define the pointed versions, and then re-define the non-pointed versions in terms of those. *)

Theorem eq_proofs_unicity A (eq_dec : forall x y : A, x = y \/ x <> y) (x : A)
: forall (y:A) (p1 p2:x = y), p1 = p2.