Definition union' (s1 s2: tree) : tree :=
match compare_height s1 s1 s2 s2 with
| Lt => fold' _ insert s1 s2
| Gt => fold' _ insert s2 s1
| Eq => linear_union s1 s2
end.

(* Specifications: *)
Lemma fold'_searchtree:
forall (f: key -> tree -> tree)
(Hf: forall k s, searchtree None None s -> searchtree None None (f k s))
s1 s2,
searchtree None None s1 -> searchtree None None s2 ->
searchtree None None (fold' _ f s1 s2).
Lemma fold'_valid: forall (f: key -> tree -> tree)
(f_valid: forall k s, valid s -> valid (f k s))
s1 s2,
valid s1 -> valid s2 -> valid (fold' _ f s1 s2).
Lemma union_valid: forall s1 s2, valid s1 -> valid s2 -> valid (union' s1 s2).
Definition diff' (s1 s2: tree) : tree :=
match compare_height s1 s1 s2 s2 with
| Lt => filter' (fun k => negb (member k s2)) s1
| Gt => fold' _ delete s2 s1
| Eq => linear_diff s1 s2
end.
Lemma diff_valid:  forall s1 s2, valid s1 -> valid s2 -> valid (diff' s1 s2).
Definition inter' (s1 s2: tree) : tree :=
match compare_height s1 s1 s2 s2 with
| Lt => filter' (fun k => member k s2) s1
| Gt => filter' (fun k => member k s1) s2
| Eq => linear_inter s1 s2
end.
Lemma inter_valid:  forall s1 s2, valid s1 -> valid s2 -> valid (inter' s1 s2).
Fixpoint elements' (x: tree) (base: list key) : list key :=
match x with
| EE => base
| T _ t1 k t2 => elements' t1 (cons k (elements' t2 base))
end.
Lemma elements'_interp : forall s x l,
SetoidList.InA E.eq x (elements' s l) <-> interp s x \/ InA E.eq x l.
Lemma union'_spec : forall s s' x, valid s -> valid s' ->
(interp (union' s s') x <-> interp s x \/ interp s' x).
Lemma filter'_spec : forall s x f,
compatb f ->
valid s ->
(interp (filter' f s) x <-> interp s x /\ f x = true).
Lemma choose'_spec1 : forall s x, searchtree None None s ->
choose' s = Some x -> interp s x.
Lemma choose'_spec2 : forall s, choose' s = None -> s=EE.
Lemma delmin_eq:
forall s x (v: searchtree None None s),
choose' s = Some x ->
delete'_min s = Some (x, delete x s).
Lemma delete_min_valid:
forall s, valid s ->
match delete'_min s with
| Some (_, s0) => valid s0
| None => True
end.
Lemma member_compat:
forall s, valid s -> Proper (E.eq ==> Logic.eq) (fun k : key => member k s).
Lemma inter'_spec : forall s s' x,
valid s -> valid s' -> (interp (inter' s s') x <-> interp s x /\ interp s' x).
Lemma diff'_spec : forall s s' x,
valid s -> valid s' -> (interp (diff' s s') x <-> interp s x /\ ~ interp s' x).
Lemma interp_dec: forall s x, {interp s x}+{~interp s x}.
Definition lt' (s s': tree):  Prop :=  compare' s s' = Lt.
Lemma lt'_strorder : StrictOrder lt'.
Lemma lt'_compat: Proper (eq ==> eq ==> iff) lt'.
Lemma min_elt'_spec2:
forall s (x : key) (y : key),
choose' s = Some x ->
interp s y ->
forall (lo hi : option key)
(ST: searchtree lo hi s), ~ E.lt y x.
Lemma Klt_strictorder: StrictOrder K.lt.
Lemma elements'_spec2 : forall s, valid s -> Sorted.sort E.lt (elements' s nil).
Definition Equal' s s' := forall a, interp s a <-> interp s' a.