Fixpoint forNats(n : nat) :=
  match n with
      | 0 => nil
      | S n' =>
        cons n' (forNats n')
  end.

(* Specifications: *)
Lemma forNats_In : forall n i, i < n <-> In i (forNats n).
Lemma forNats_NoDup : forall n, NoDup (forNats n).
Lemma forNats_length : forall n, length (forNats n) = n.
Lemma sumList_forNats_first_ls : forall (n : nat)(f : nat -> Rat), n <> O -> f O <= sumList (forNats n) f.
Lemma flatten_map_eq : forall (A B : Set)(ls : list A)(f : A -> B), flatten (map (fun a => (f a) :: nil) ls) = map f ls.
Lemma app_NoDup_inv : forall (A : Set)(ls1 ls2 : list A), NoDup (ls1 ++ ls2) -> (forall a, In a ls1 -> In a ls2 -> False).
Lemma flatten_NoDup : forall (A : Set)(ls : list (list A)), NoDup ls -> (forall x, In x ls -> NoDup x) -> (forall x1 x2, In x1 ls -> In x2 ls -> x1 <> x2 -> NoDup (x1 ++ x2)) -> NoDup (flatten ls).
Lemma map_NoDup' : forall (A B : Set) (ls : list A) (f : A -> B), NoDup ls -> (forall a1 a2 : A, In a1 ls -> In a2 ls ->a1 <> a2 -> f a1 <> f a2) -> NoDup (map f ls).
Lemma getUnique_cons : forall (A : Set)(eqd : eq_dec A)(ls2 ls1 : list A) a, a :: ls1 = (getUnique ls2 eqd) -> exists ls3 ls4, ls2 = ls3 ++ (a :: ls4) /\ ls1 = (getUnique ls4 eqd).
Lemma getUnique_eq_inv : forall (A : Set)(a : A)(eqd1 eqd2 : eq_dec A)(ls1 ls2 : list A), getUnique ls1 eqd1 = getUnique ls2 eqd2 -> In a ls1 -> In a ls2.
Lemma filter_all_true : forall (A : Set)(ls : list A)(P : A -> bool), (forall a, In a ls -> P a = true) -> filter P ls = ls.
Lemma filter_cons : forall (A : Set)(P : A -> bool)(ls : list A) a, filter P (a :: ls) = if (P a) then (a :: (filter P ls)) else (filter P ls).
Theorem fold_left_orb_true_init : forall (A : Type)(f : A -> bool)(ls : list A), fold_left (fun b x => orb b (f x)) ls true = true.
Theorem fold_left_orb_true_in : forall (A : Type)(f : A -> bool)(ls : list A) a init, In a ls -> f a = true -> fold_left (fun b x => orb b (f x)) ls init = true.
Theorem hd_error_Some_In : forall (A : Type)(ls : list A) a, hd_error ls = Some a -> In a ls.
Theorem fold_and_false_init : forall (A : Type)(ls : list A) P, fold_left (fun b z => b && negb (P z)) ls false = false.
Theorem hd_filter_false_eq_and_false : forall (A : Type)(ls : list A)(P : A -> bool), (if hd_error (filter P ls) then false else true) = fold_left (fun (b : bool) (z : A) => b && negb (P z)) ls true.
Theorem fst_split_eq_list_pred : forall (A B : Set)(ls1 : list (A * B))(ls2 : list A), list_pred (fun a b => fst a = b) ls1 ls2 -> fst (split ls1) = ls2.
Theorem snd_split_eq_list_pred : forall (A B : Set)(ls1 : list (B * A))(ls2 : list A), list_pred (fun a b => snd a = b) ls1 ls2 -> snd (split ls1) = ls2.
Theorem combine_map_eq : forall (A B C : Type)(lsa : list A)(lsb : list B)(f : B -> C), combine lsa (map f lsb) = map (fun p => (fst p, f (snd p))) (combine lsa lsb).
Theorem map_ext_pred : forall (A B C : Set)(P : A -> B -> Prop)(lsa : list A)(lsb : list B)(f1 : A -> C)(f2 : B -> C), list_pred P lsa lsb -> (forall a b, P a b -> (f1 a) = (f2 b)) -> map f1 lsa = map f2 lsb.
Theorem list_pred_combine_l_h : forall (A C : Set)(lsa : list A)(lsc : list C) P1, list_pred P1 lsa lsc -> forall (B : Set)(lsb : list B) P2, list_pred P2 lsb lsc -> list_pred (fun p c => P1 (fst p) c /\ P2 (snd p) c) (combine lsa lsb) lsc.
Theorem list_pred_combine_l : forall (A B C : Set)P1 P2 (lsa : list A)(lsb : list B)(lsc : list C), list_pred P1 lsa lsc -> list_pred P2 lsb lsc -> list_pred (fun p c => P1 (fst p) c /\ P2 (snd p) c) (combine lsa lsb) lsc.
Lemma list_pred_symm : forall (A B : Set)(P : A -> B -> Prop) lsa lsb, list_pred (fun b a => P a b) lsb lsa -> list_pred P lsa lsb.
Theorem list_pred_combine_r : forall (A B C : Set) (P1 : A -> B -> Prop) (P2 : A -> C -> Prop) (lsa : list A) (lsb : list B) (lsc : list C), list_pred P1 lsa lsb -> list_pred P2 lsa lsc -> list_pred (fun a p => P1 a (fst p) /\ P2 a (snd p)) lsa (combine lsb lsc).