Fixpoint revflatten {A: Type} (xss: list (list A)) : list A :=
match xss with
| []       => []
| xs::xss' => revflatten xss' ++ xs
end.

(* Specifications: *)
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 seq_S start len : seq start (S len) = seq start len ++ [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.
Section count_occ.
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).