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).

(* Specifications: *)
Lemma if_true : forall {A : Type} b (x y : A)
(Htrue: is_true b),
(if b then x else y) = x.
Lemma nth_error_app_inv:
forall (A : Type) (i : nat) (v: A) (ys xs : seq.seq A), nth_error xs i = Some v ->
nth_error (xs ++ ys) i = Some v.