Corollary upd_Znth_eq' : forall {A}{d: Inhabitant A} x (l1 l2 : list A) i (Hi : 0 <= i < Zlength l1)
  (Hlen : Zlength l1 = Zlength l2)
  (Heq : forall j, 0 <= j < Zlength l1 -> j <> i -> Znth j l1 = Znth j l2),
  upd_Znth i l1 x = upd_Znth i l2 x.

(* Specifications: *)
Lemma upd_Znth_twice : forall {A} i l (x y : A), 0 <= i < Zlength l -> upd_Znth i (upd_Znth i l x) y = upd_Znth i l y.
Lemma hd_Znth : forall {A}{d: Inhabitant A} (l : list A), hd default l = Znth 0 l.
Lemma NoDup_filter : forall {A} (f : A -> bool) l, NoDup l -> NoDup (filter f l).
Lemma Permutation_Zlength : forall {A} (l1 l2 : list A), Permutation.Permutation l1 l2 -> Zlength l1 = Zlength l2.
Lemma Permutation_filter : forall {A} (f : A -> bool) l1 l2, Permutation.Permutation l1 l2 -> Permutation.Permutation (filter f l1) (filter f l2).
Lemma NoDup_add : forall {A} l1 l2 (x : A), NoDup (l1 ++ l2) -> ~In x (l1 ++ l2) -> NoDup (l1 ++ x :: l2).
Lemma list_in_count : forall {A} {A_eq : EqDec A} (l l' : list A), NoDup l' -> (length (filter (fun x => if in_dec eq_dec x l then true else false) l') <= length l)%nat.
Lemma filter_length : forall {A} (f : A -> bool) l, length l = (length (filter f l) + length (filter (fun x => negb (f x)) l))%nat.
Lemma Zlength_filter : forall {A} f (l : list A), Zlength (filter f l) <= Zlength l.
Lemma Zlength_concat : forall {A} (l : list (list A)), Zlength (concat l) = fold_right Z.add 0 (map (@Zlength A) l).
Lemma Zlength_concat_le : forall {A} (l : list (list A)) n, Forall (fun l => Zlength l <= n) l -> Zlength (concat l) <= n * Zlength l.
Lemma filter_app : forall {A} (f : A -> bool) l1 l2, filter f (l1 ++ l2) = filter f l1 ++ filter f l2.
Lemma filter_concat : forall {A} f (l : list (list A)), filter f (concat l) = concat (map (filter f) l).
Lemma NoDup_upto : forall n, NoDup (upto n).
Lemma In_remove : forall {A} {A_eq : EqDec A} (x y : A) l, In x (remove A_eq y l) <-> In x l /\ x <> y.
Lemma remove_NoDup : forall {A} {A_eq : EqDec A} (x : A) l, NoDup l -> NoDup (remove A_eq x l).
Lemma remove_out : forall {A} {A_eq : EqDec A} (x : A) l, ~In x l -> remove A_eq x l = l.
Lemma remove_from_NoDup : forall {A} {A_eq : EqDec A} (x : A) l1 l2, NoDup (l1 ++ x :: l2) -> remove A_eq x (l1 ++ x :: l2) = l1 ++ l2.
Lemma incl_remove_add : forall {A} {A_eq : EqDec A} (x : A) l1 l2, incl l1 l2 -> incl l1 (x :: remove A_eq x l2).
Lemma list_pigeonhole : forall l n, Zlength l < n -> exists a, 0 <= a < n /\ ~In a l.
Lemma In_sublist_upto : forall n x i j, In x (sublist i j (upto n)) -> 0 <= i -> i <= x < j /\ x < Z.of_nat n.
Lemma incl_cons_iff : forall {A} (a : A) b c, incl (a :: b) c <-> In a c /\ incl b c.
Lemma lt_le_1 : forall i j, i < j <-> i + 1 <= j.
Lemma firstn_all : forall {A} n (l : list A), (length l <= n)%nat -> firstn n l = l.
Lemma sublist_all : forall {A} i (l : list A), Zlength l <= i -> sublist 0 i l = l.
Lemma sublist_prefix : forall {A} i j (l : list A), sublist 0 i (sublist 0 j l) = sublist 0 (Z.min i j) l.
Lemma sublist_suffix : forall {A} i j (l : list A), 0 <= i -> 0 <= j -> sublist i (Zlength l - j) (sublist j (Zlength l) l) = sublist (i + j) (Zlength l) l.
Lemma sublist_parts1 : forall {A} i j (l : list A), 0 <= i -> sublist i j l = sublist i j (sublist 0 j l).
Lemma sublist_parts2 : forall {A} i j (l : list A), 0 <= i -> j <= Zlength l -> sublist i j l = sublist 0 (j - i) (sublist i (Zlength l) l).
Lemma Forall_Forall2 : forall {A} (P : A -> Prop) Q l1 l2 (HP : Forall P l1) (HQ : Forall2 Q l1 l2) (Htransfer : forall x y, P x -> Q x y -> P y), Forall P l2.
Lemma Forall_suffix_max : forall {A} (P : A -> Prop) l1 l2 i j (Hi : 0 <= i <= Zlength l1) (Hj : 0 <= j <= Zlength l1) (Hl1 : Forall P (sublist j (Zlength l1) l1)) (Hl2 : sublist i (Zlength l1) l1 = sublist i (Zlength l2) l2), Forall P (sublist (Z.max i j) (Zlength l2) l2).