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
  }.Class monad (mon : Type -> Type) :=
  {
    ret : forall {A : Type},  A -> mon A;
    bind : forall {A B : Type}, mon A -> (A -> mon B) -> mon B
  }.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 "'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 if_false : forall {A : Type} b (x y : A) (Hfalse: is_true (~~b)), (if b then x else y) = y.
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.
Lemma app_eq_refl_nil: forall {A:Type} (xs ys : list A), xs = xs ++ ys -> ys = nil.
Lemma app_assoc_l: forall (A : Type) (l m n : seq.seq A), l ++ m ++ n = l ++ (m ++ n).
Lemma nth_error_app: forall {A:Type} i (ys xs : list A), nth_error xs i = nth_error (ys ++ xs) (length ys + i).
Lemma list_cons_irrefl: forall {A: Type} (x : A) xs, ~ x :: xs = xs.
Lemma lt_succ_neq: forall x y z, (x <= y < x + Z.succ z)%Z -> y <> (x + z)%Z -> (x <= y < x + z)%Z.
Lemma le_sub: forall x y z, (x < z)%positive -> (z <= y)%positive -> (x <= Z.to_pos (Z.pos_sub y (z - x)))%positive.
Lemma lt_sub_bound: forall x y, (x < y)%positive -> (Z.to_pos (Z.pos_sub y (y - x)) < Pos.succ x)%positive.
Lemma lt_lt_sub: forall a b c, (a < b)%positive -> (b <= c)%positive -> (b - a < c)%positive.
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)).
Lemma forall_and: forall {A : Type} (f g : A -> Prop), (forall x : A, f x /\ g x) <-> (forall x : A, f x) /\ (forall x : A, g x).
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).