From mathcomp.ssreflect Require Import ssreflect ssrbool ssrnat eqtype seq.
Set Implicit Arguments.
(* tactics to support Omega for ssrnats*)
Ltac arith_hypo_ssrnat2coqnat :=
match goal with
| H : context [andb _ _] |- _ => let H0 := fresh in case/andP: H => H H0
| H : context [orb _ _] |- _ => case/orP: H => H
| H : context [?L <= ?R] |- _ => move/leP: H => H
| H : context [?L < ?R] |- _ => move/ltP : H => H
| H : context [?L == ?R] |- _ => move/eqP : H => H
| H : context [addn ?L ?R] |- _ => rewrite -plusE in H
| H : context [muln ?L ?R] |- _ => rewrite -multE in H
| H : context [subn ?L ?R] |- _ => rewrite -minusE in H
end.
Ltac arith_goal_ssrnat2coqnat :=
rewrite ?NatTrec.trecE -?plusE -?minusE -?multE -?leqNgt -?ltnNge;
repeat match goal with
| |- is_true (andb _ _) => apply/andP; split
| |- is_true (orb _ _) => try apply/orP
| |- is_true (_ <= _) => try apply/leP
| |- is_true (_ < _) => try apply/ltP
end.
Ltac ssromega :=
repeat arith_hypo_ssrnat2coqnat;
arith_goal_ssrnat2coqnat; simpl;
omega.
Class monad (mon : Type -> Type) :=
{
ret : forall {A : Type},  A -> mon A;
bind : forall {A B : Type}, mon A -> (A -> mon B) -> mon B
}.
Notation "x >>= f" := (bind x f) (at level 40, left associativity).
Notation "'do!' X <- A ; B" := (bind A (fun X => B)) (at level 40).
intros.
generalize dependent i.
generalize dependent v.
induction xs;
intros.
rewrite Coqlib.nth_error_nil in H.
discriminate.
destruct i; simpl in *;
now auto.
Qed.

Lemma prod_fun :
forall {A B C : Type}
(f g: A -> (B * C)),
f = g ->
(fun x : A => fst (f x)) =  (fun x : A => fst (g x)) /\
(fun x : A => snd (f x)) = (fun x : A => snd (g x)).