(** ** Treeify *)
Notation ifpred p n := (if p then pred n else n%nat).
Definition treeify_invariant size (f:treeify_t) :=
forall acc,
size <= length acc ->
let (t,acc') := f acc in
cardinal t = size /\ acc = elements t ++ acc'.

(* Specifications: *)
Lemma treeify_zero_spec : treeify_invariant 0 treeify_zero.
Lemma treeify_one_spec : treeify_invariant 1 treeify_one.
Lemma treeify_cont_spec f g size1 size2 size :
treeify_invariant size1 f ->
treeify_invariant size2 g ->
size = S (size1 + size2) ->
treeify_invariant size (treeify_cont f g).
Lemma treeify_aux_spec n (p:bool) :
treeify_invariant (ifpred p (Pos.to_nat n)) (treeify_aux p n).
Lemma plength_aux_spec l p :
Pos.to_nat (plength_aux l p) = length l + Pos.to_nat p.
Lemma plength_spec l : Pos.to_nat (plength l) = S (length l).
Lemma treeify_elements l : elements (treeify l) = l.
Lemma treeify_spec x l : InT x (treeify l) <-> InA X.eq x l.
Lemma treeify_ok l : sort X.lt l -> Ok (treeify l).
(** ** Filter *)
Lemma filter_aux_elements s f acc :
filter_aux f s acc = List.filter f (elements s) ++ acc.
Lemma filter_elements s f :
elements (filter f s) = List.filter f (elements s).
Lemma filter_spec s x f :
Proper (X.eq==>Logic.eq) f ->
(InT x (filter f s) <-> InT x s /\ f x = true).