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 forall2_and:
forall {A B : Type} (f g : A -> B -> Prop),
(forall x y, f x y /\ g x y) <->
(forall x y, f x y) /\ (forall x y, g x y).