Corollary combine_upd_Znth1 : forall {A B}{d: Inhabitant B} (l1 : list A) (l2 : list B) i x,
   0 <= i < Zlength l1 ->
  Zlength l1 = Zlength l2 ->
   combine (upd_Znth i l1 x) l2 = upd_Znth i (combine l1 l2) (x, Znth i l2).Corollary combine_upd_Znth2 : forall {A B}{d: Inhabitant A} (l1 : list A) (l2 : list B) i x, 0 <= i < Zlength l1 ->
  Zlength l1 = Zlength l2 -> combine l1 (upd_Znth i l2 x) = upd_Znth i (combine l1 l2) (Znth i l1, x).

(* Specifications: *)
Lemma in_concat : forall {A} (l : list (list A)) x, In x (concat l) <-> exists l1, In x l1 /\ In l1 l.
Lemma length_concat : forall {A} (l : list (list A)), length (concat l) = fold_right plus O (map (@length A) l).
Lemma length_concat_min : forall {A}{d: Inhabitant A} (l : list (list A)) i (Hi : 0 <= i < Zlength l), (length (Znth i l) <= length (concat l))%nat.
Lemma length_concat_upd : forall {A} {d: Inhabitant A} l i (l' : list A) (Hi : 0 <= i < Zlength l), length (concat (upd_Znth i l l')) = (length (concat l) + length l' - length (Znth i l))%nat.
Lemma sepcon_rev : forall l, fold_right sepcon emp (rev l) = fold_right sepcon emp l.
Lemma incl_cons_out : forall {A} (a : A) l1 l2, incl l1 (a :: l2) -> ~In a l1 -> incl l1 l2.
Lemma In_upto : forall n i, In i (upto n) <-> 0 <= i < Z.of_nat n.
Lemma combine_fst : forall {A B} (l : list A) (l' : list B), length l = length l' -> map fst (combine l l') = l.
Lemma combine_snd : forall {A B} (l : list A) (l' : list B), length l = length l' -> map snd (combine l l') = l'.
Lemma rev_combine : forall {A B} (l1 : list A) (l2 : list B), length l1 = length l2 -> rev (combine l1 l2) = combine (rev l1) (rev l2).
Lemma combine_map_snd : forall {A B C} (l1 : list A) (l2 : list B) (f : B -> C), combine l1 (map f l2) = map (fun x => let '(a, b) := x in (a, f b)) (combine l1 l2).
Lemma combine_const1 : forall {A B} (l1 : list A) (x : B) n, Z.of_nat n >= Zlength l1 -> combine l1 (repeat x n) = map (fun a => (a, x)) l1.
Lemma combine_const2 : forall {A B} (x : A) n (l2 : list B), Z.of_nat n >= Zlength l2 -> combine (repeat x n) l2 = map (fun b => (x, b)) l2.
Lemma map_const: forall {A B} (c : A) (l : list B), map (fun _ => c) l = repeat c (length l).
Lemma In_upd_Znth : forall {A} i l (x y : A), In x (upd_Znth i l y) -> x = y \/ In x l.
Lemma upd_Znth_In : forall {A} i l (x : A), In x (upd_Znth i l x).
Lemma NoDup_Znth_iff : forall {A}{d: Inhabitant A} (l : list A), NoDup l <-> forall i j (Hi : 0 <= i < Zlength l) (Hj : 0 <= j < Zlength l), Znth i l = Znth j l -> i = j.
Lemma concat_less_incl : forall {A} l i (l1 l2 : list A) (Hi : 0 <= i < Zlength l) (Hless : Znth i l = l1 ++ l2), incl (concat (upd_Znth i l l1)) (concat l).
Lemma NoDup_app : forall {A} (l1 l2 : list A), NoDup (l1 ++ l2) -> NoDup l1 /\ NoDup l2 /\ forall x, In x l1 -> ~In x l2.
Lemma NoDup_app_iff : forall {A} (l1 l2 : list A), NoDup (l1 ++ l2) <-> NoDup l1 /\ NoDup l2 /\ forall x, In x l1 -> ~In x l2.