Section equiv.
Variable eqv : forall x, relation (F x).
Inductive equiv_hlist : forall ls, hlist ls -> hlist ls -> Prop :=
| hlist_eqv_nil : equiv_hlist Hnil Hnil
| hlist_eqv_cons : forall l ls x y h1 h2, eqv x y -> equiv_hlist h1 h2 ->
@equiv_hlist (l :: ls) (Hcons x h1) (Hcons y h2).
Global Instance Reflexive_equiv_hlist (R : forall t, Reflexive (@eqv t)) ls
: Reflexive (@equiv_hlist ls).
Global Instance Symmetric_equiv_hlist (R : forall t, Symmetric (@eqv t)) ls
: Symmetric (@equiv_hlist ls).
Global Instance Transitive_equiv_hlist (R : forall t, Transitive (@eqv t)) ls
: Transitive (@equiv_hlist ls).
Global Instance Injection_equiv_hlist_cons ls i a b (c : hlist ls) d
: Injective (equiv_hlist (Hcons a c) (@Hcons i ls b d)) :=
{ result := @eqv i a b /\ equiv_hlist c d
; injection := @equiv_hlist_Hcons _ _ _ _ _ _ }.
Global Instance Injection_equiv_hlist_app a b (c c' : hlist a) (d d' : hlist b)
: Injective (equiv_hlist (hlist_app c d) (hlist_app c' d')) :=
{ result := equiv_hlist c c' /\ equiv_hlist d d'
; injection := fun x => proj2 (@equiv_hlist_app _ _ _ _ _ _) x }.
End equiv.
Global Instance Injection_hlist_cons ls t (a : F t) (b : hlist ls) c d
: Injective (Hcons a b = Hcons c d) :=
{ result := a = c /\ b = d
; injection := @Hcons_inv t ls a b c d
}.

Theorem equiv_eq_eq : forall ls (x y : hlist ls),
equiv_hlist (fun x => @eq _) x y <-> x = y.