Fact interval_dec a b i : { a <= i < b } + { i < a \/ b <= i }.(* Fact interval_dec a b n : { a <= n < b } + { ~ a <= n < b }.
Proof.
  destruct (le_lt_dec a n).
  2: right; omega.
  destruct (le_lt_dec b n).
  1: right; omega.
  left; omega.
Qed. *)


Definition lsum := fold_right plus 0.Definition lmax := fold_right max 0.Fact lmax_spec l x : lmax l <= x <-> Forall (fun y => y <= x) l.Fact lsum_app l r : lsum (l++r) = lsum l+lsum r.Definition nat_new l := S (lmax l).Fact nat_new_spec l : ~ In (nat_new l) l.Local Notation Zero := false.Local Notation One  := true.Fixpoint div2 n : nat * bool :=
  match n with
    | 0 => (0,Zero)
    | 1 => (0,One)
    | S (S n) => let (p,b) := div2 n in (S p,b)
  end.Fact div2_spec n : match div2 n with 
                     | (p,One)  => n = 2*p+1 
                     | (p,Zero) => n = 2*p
                   end.Fixpoint div2_2p1 p : div2 (2*p+1) = (p,One).Fixpoint div2_2p0 p : div2 (2*p) = (p,Zero).Fixpoint pow2 p := 
  match p with 
    | 0   => 1
    | S p => 2*pow2 p
  end.Definition find_pow2 x := S (loop (pred x) x).Fact find_pow2_geq x : 1 <= find_pow2 x.Fact find_pow2_prop x : x <= pow2 (find_pow2 x).Definition nat_sorted ll := forall l a m b r, ll = l ++ a :: m ++ b :: r -> a < b.Fact in_nat_sorted_0 : nat_sorted nil.Fact in_nat_sorted_1 x : nat_sorted (x::nil).Fact in_nat_sorted_2 x y ll : x < y -> nat_sorted (y::ll) -> nat_sorted (x::y::ll).Fact in_nat_sorted_3 x ll : Forall (lt x) ll -> nat_sorted ll -> nat_sorted (x::ll).Fact nat_sorted_cons_inv x ll : nat_sorted (x::ll) -> nat_sorted ll.Fact nat_sorted_Forall x ll : nat_sorted (x::ll) -> Forall (lt x) ll.Fact nat_sorted_head_inv x y ll : nat_sorted (x::y::ll) -> x < y.

(* Specifications: *)
Theorem nat_sorted_rect l : nat_sorted l -> P l.