Section PARTITION_BETWEEN.
Variable above_low_bound: elt -> bool.
Variable below_high_bound: elt -> bool.
Fixpoint raw_partition_between (m: Raw.tree) : Raw.tree * Raw.tree :=
match m with
| Raw.Leaf => (Raw.Leaf, Raw.Leaf)
| Raw.Node _ l x r =>
if above_low_bound x then
if below_high_bound x then
(let (l1, l2) := raw_partition_between l in
let (r1, r2) := raw_partition_between r in
(Raw.join l1 x r1, Raw.concat l2 r2))
else
(let (l1, l2) := raw_partition_between l in
(l1, Raw.join l2 x r))
else
(let (r1, r2) := raw_partition_between r in
(r1, Raw.join l x r2))
end.
Remark In_raw_partition_between_1:
forall x m,
Raw.In x (fst (raw_partition_between m)) -> Raw.In x m.
Remark In_raw_partition_between_2:
forall x m,
Raw.In x (snd (raw_partition_between m)) -> Raw.In x m.
Hypothesis above_monotone:
forall x1 x2, X.eq x1 x2 \/ X.lt x1 x2 -> above_low_bound x1 = true -> above_low_bound x2 = true.
Hypothesis below_monotone:
forall x1 x2, X.eq x1 x2 \/ X.lt x2 x1 -> below_high_bound x1 = true -> below_high_bound x2 = true.
Remark In_raw_partition_between_3:
forall x m,
Raw.In x (fst (raw_partition_between m)) -> above_low_bound x = true /\ below_high_bound x = true.
Remark In_raw_partition_between_4:
forall x m,
Raw.bst m ->
Raw.In x (snd (raw_partition_between m)) -> above_low_bound x = false \/ below_high_bound x = false.
Remark In_raw_partition_between_5:
forall x m,
Raw.bst m ->
Raw.In x m -> above_low_bound x = true -> below_high_bound x = true ->
Raw.In x (fst (raw_partition_between m)).
Remark In_raw_partition_between_6:
forall x m,
Raw.bst m ->
Raw.In x m -> above_low_bound x = false \/ below_high_bound x = false ->
Raw.In x (snd (raw_partition_between m)).
Definition partition_between (s: t) : t * t :=
let p := raw_partition_between s.(MSet.this) in
(@MSet.Mkt (fst p) (proj1 (raw_partition_between_ok s.(MSet.this) s.(MSet.is_ok))),
@MSet.Mkt (snd p) (proj2 (raw_partition_between_ok s.(MSet.this) s.(MSet.is_ok)))).

Theorem partition_between_iff_2:
forall x s,
In x (snd (partition_between s)) <->
In x s /\ (above_low_bound x = false \/ below_high_bound x = false).