(* Transport equality, only matching on eq_refl in contradictory cases, to make sure
   terms using this function reduce *)
Fixpoint nat_cast (P : nat -> Type) {n m} : n = m -> P n -> P m.

(* Specifications: *)
Lemma nat_cast_eq_rect: forall (P : nat -> Type), forall (n m : nat) (e: n = m) (pn: P n), nat_cast P e pn = eq_rect n P pn m e.
Lemma nat_cast_proof_irrel: forall (P : nat -> Type), forall (n m : nat) (e1 e2: n = m) (pn: P n), nat_cast P e1 pn = nat_cast P e2 pn.
Lemma nat_cast_same: forall (P: nat -> Type) (s: nat) (n: P s), nat_cast P eq_refl n = n.
Lemma nat_cast_fuse: forall (P: nat -> Type) (n1 n2 n3: nat) (e12: n1 = n2) (e23: n2 = n3) (x: P n1), nat_cast P e23 (nat_cast P e12 x) = nat_cast P (eq_trans e12 e23) x.
Lemma nat_cast_cast ni no (pf: ni = no) (P: nat -> Type) (x : P ni): nat_cast P pf x = match pf in _ = Y return P Y with | eq_refl => x end.