Inductive Exists2 {A B} (R: A -> B -> Prop) : list A -> list B -> Prop :=
 | Exists2_cons_hd : forall x xs y ys, R x y -> Exists2 R (x::xs) (y::ys)
 | Exists2_cons_tl : forall x xs y ys, Exists2 R xs ys -> Exists2 R (x::xs) (y::ys).Inductive Exists2 {A B} (R: A -> B -> Prop) : list A -> list B -> Prop :=
 | Exists2_cons_hd : forall x xs y ys, R x y -> Exists2 R (x::xs) (y::ys)
 | Exists2_cons_tl : forall x xs y ys, Exists2 R xs ys -> Exists2 R (x::xs) (y::ys).Inductive Exists2 {A B} (R: A -> B -> Prop) : list A -> list B -> Prop :=
 | Exists2_cons_hd : forall x xs y ys, R x y -> Exists2 R (x::xs) (y::ys)
 | Exists2_cons_tl : forall x xs y ys, Exists2 R xs ys -> Exists2 R (x::xs) (y::ys).

(* Specifications: *)
Lemma Exists2_exists A (d: A) (R: A -> A -> Prop) (xs ys: list A) : Exists2 R xs ys -> exists i, i < length xs /\ R (nth i xs d) (nth i ys d).
Lemma app_eq_compat_l {A: Type} (xs ys zs: list A) : ys = zs -> xs ++ ys = xs ++ zs.
Lemma In_prefix_suffix (A : Type) (a : A) l : In a l -> exists l1 l2, l = l1 ++ a :: l2.
Lemma forall_exists_list (A B : Type) (P : A -> Prop) (Q : A -> B -> Prop) (l : list A) : (forall a, In a l -> P a -> exists b, Q a b) -> (Forall P l -> exists l', Forall2 Q l l').
Lemma forall_andl (A: Type) (P: A -> Prop) (l: list A): Forall P l <-> andl (map P l).
Lemma Permutation_flat_map_ext A B : forall l (f g : A -> list B), (forall x, In x l -> Permutation (f x) (g x)) -> Permutation (flat_map f l) (flat_map g l).
Lemma Permutation_revflatten A B (f : A -> list B) l : Permutation(revflatten (map f l)) (flat_map f l).
Lemma In_seq n start len : In n (seq start len) <-> start <= n < start+len.
Lemma plus_eq_compat_l x y1 y2 : y1 = y2 -> x + y1 = x + y2.
Lemma plus_eq_compat_r x1 x2 y : x1 = x2 -> x1 + y = x2 + y.
Lemma count_occ_remove_O A eq_dec (a: A) l : count_occ eq_dec (remove eq_dec a l) a = 0.
Lemma count_occ_remove_neq A eq_dec (a a': A) l : a<>a' -> count_occ eq_dec (remove eq_dec a' l) a = count_occ eq_dec l a.
Lemma suml_map_count_occ_remove A eq_dec (a: A) l1 l2 : ~In a l2 -> suml (map (count_occ eq_dec (remove eq_dec a l1)) l2) = suml (map (count_occ eq_dec l1) l2).
Lemma length_remove_count_occ A eq_dec (a: A) l: length l = length (remove eq_dec a l) + count_occ eq_dec l a.
Lemma in_remove_neq A eq_dec (a a': A) l : In a' (remove eq_dec a l) -> In a' l.
Lemma length_count_occ a b l : (forall n, In n l -> a <= n < a + b) -> length l = suml (map (count_occ eq_nat_dec l) (seq a b)).
Lemma count_occ_cons A eq_dec (a a': A) l : count_occ eq_dec (a::l) a' = if eq_dec a a' then S (count_occ eq_dec l a') else count_occ eq_dec l a'.
Lemma count_occ_app A eq_dec (a :A) l l' : count_occ eq_dec (l ++ l') a = count_occ eq_dec l a + count_occ eq_dec l' a.
Lemma count_occ_flat_map A B eq_B_dec (f: A -> list B) b l : count_occ eq_B_dec (flat_map f l) b = suml (map (fun a => count_occ eq_B_dec (f a) b) l).
Lemma tl_incl (A:Type): forall (a:A) l l', incl (a::l') l -> incl l' l.
Lemma NoDup_app (A: Type) (l1 l2: list A): (forall x, In x l1 -> ~ In x l2) -> NoDup l1 -> NoDup l2 -> NoDup (l1 ++ l2).
Lemma NoDup_split (A: Type) (l1 l2: list A): NoDup (l1 ++ l2) -> NoDup l1.
Lemma NoDup_split_right : forall (A : Type) (l1 l2 : list A), NoDup (l1 ++ l2) -> NoDup l2.
Theorem NoDup_cons_iff {A:Type} (a: A) (l: list A): NoDup (a::l) <-> ~ In a l /\ NoDup l.
Lemma NoDup_app_in_l A l l' : NoDup (l ++ l') -> forall x : A, (In x l) -> ~ (In x l').
Lemma NoDup_Permutation_NoDup A l l' : @NoDup A l -> Permutation.Permutation l l' -> NoDup l'.
Lemma NoDup_incl_le_length (A: Type) (l1 l2: list A): NoDup l1 -> incl l1 l2 -> length l1 <= length l2.
Lemma NoDup_flat_map A B (f : A -> list B) l : (forall x, In x l -> NoDup (f x)) -> NoDup l -> (forall x y, In x l -> In y l -> x <> y -> (forall z, In z (f x) <-> ~ In z (f y))) -> NoDup (flat_map f l).
Lemma lt_0_pow x n : 0 < x -> 0 < Nat.pow x n.
Lemma pow_le_compat x y n: x <= y -> Nat.pow x n <= Nat.pow y n.
Lemma length_filter (A B : Type) (c : B -> bool) (f : A -> B) (xs : list A) : length (filter (fun x => c (f x)) xs) = length (filter c (map f xs)).