Program Definition EqSetoid (A:Type) : Setoid A := @Build_Setoid A (@eq A) _.Program Instance ProdSetoid `(Setoid A) `(Setoid B) : Setoid (A * B) :=
  { equiv := fun z w => equiv (fst z) (fst w) /\ equiv (snd z) (snd w)
  }.Inductive Mor `(As:Setoid A) `(Bs:Setoid B) :=
  { mor_fun :> A -> B
  ; mor_prf :> @Morphism (A -> B) (equiv ==> equiv)%signature mor_fun
  }.Inductive Mor `(As:Setoid A) `(Bs:Setoid B) :=
  { mor_fun :> A -> B
  ; mor_prf :> @Morphism (A -> B) (equiv ==> equiv)%signature mor_fun
  }.Inductive Mor `(As:Setoid A) `(Bs:Setoid B) :=
  { mor_fun :> A -> B
  ; mor_prf :> @Morphism (A -> B) (equiv ==> equiv)%signature mor_fun
  }.Program Definition fstM `{As:Setoid A} `{Bs:Setoid B} : Mor (ProdSetoid As Bs) As
 := Build_Mor _ _ (@fst A B) _.Program Definition sndM `{As:Setoid A} `{Bs:Setoid B} : Mor (ProdSetoid As Bs) Bs
 := Build_Mor _ _ (@snd A B) _.Definition ext_equiv `(As:Setoid A) `(Bs:Setoid B) : relation (Mor As Bs) :=
  fun f g => forall a a':A, a == a' -> f a == g a'.

(* Specifications: *)
Lemma ext_is_equiv `(As:Setoid A) `(Bs:Setoid B) : Equivalence (ext_equiv As Bs).