Fixpoint nats (b: nat) (w: nat) {struct w}: list nat :=
  match w with
  | 0 => nil
  | S w' => b :: nats (S b) w'
  end.

(* Specifications: *)
Lemma nats_length (w b: nat): length (nats b w) = w.
Lemma In_nats (w x b: nat): b <= x -> x < b + w -> In x (nats b w).
Lemma In_nats_inv (w x b: nat): In x (nats b w) -> b <= x < b + w.
Lemma NoDup_nats (w b: nat): NoDup (nats b w).
Lemma nats_plus y x z: nats x (y + z) = nats x y ++ nats (y + x) z.
Lemma nats_Sw b w: nats b (S w) = b :: nats (S b) w.
Lemma nats_split (w b i: nat): i <= w -> nats b w = nats b i ++ nats (b + i) (w - i).
Lemma nats_Sw' w b: nats b (S w) = nats b w ++ (w + b :: nil).
Lemma split_pow2_range n: nats 1 (pow 2 n) = 1 :: concat (map (fun x => nats (pow 2 x + 1) (pow 2 x)) (nats 0 n)).
Lemma nats_Sb w b: nats (S b) w = map S (nats b w).
Lemma filtered_sort (T: Set) (R: relation T) (P: preorder T R) (p: T -> T -> bool) (pc: forall x y, p y x = true -> ~ R y x) (l: list T): vec.sorted R l -> elemsR le (map (fun x => length (filter (p (fst x)) (snd x))) (splits l)) (nats 0 (length l)).