(* *********************************************************************)
(*                                                                     *)
(*              The Compcert verified compiler                         *)
(*                                                                     *)
(*          Xavier Leroy, INRIA Paris-Rocquencourt                     *)
(*                                                                     *)
(*  Copyright Institut National de Recherche en Informatique et en     *)
(*  Automatique.  All rights reserved.  This file is distributed       *)
(*  under the terms of the GNU General Public License as published by  *)
(*  the Free Software Foundation, either version 2 of the License, or  *)
(*  (at your option) any later version.  This file is also distributed *)
(*  under the terms of the INRIA Non-Commercial License Agreement.     *)
(*                                                                     *)
(* *********************************************************************)
(** An extension of [FSetAVL] (finite sets as balanced binary search trees) with extra interval-based operations, more efficient than standard operations. *)
Require FSetAVL.
Module Make(X: OrderedType).
Include FSetAVL.Make(X).
Module Raw := MSet.Raw.
Section MEM_BETWEEN.
(** [mem_between above below s] is [true] iff there exists an element of [s] that belongs to the interval described by the predicates [above] and [below]. Using the monotonicity of [above] and [below], the implementation of [mem_between] avoids traversing the subtrees of [s] that lie entirely outside the interval of interest. *)
Variable above_low_bound: elt -> bool.
Variable below_high_bound: elt -> bool.
Fixpoint raw_mem_between (m: Raw.tree) : bool :=
match m with
| Raw.Leaf => false
| Raw.Node _ l x r =>
if above_low_bound x
then if below_high_bound x
then true
else raw_mem_between l
else raw_mem_between r
end.
Definition mem_between (m: t) : bool := raw_mem_between m.(MSet.this).
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.

(* Specifications: *)
Lemma raw_mem_between_1:
forall m,
raw_mem_between m = true ->
exists x, Raw.In x m /\ above_low_bound x = true /\ below_high_bound x = true.
Lemma raw_mem_between_2:
forall x m,
Raw.bst m ->
Raw.In x m -> above_low_bound x = true -> below_high_bound x = true ->
raw_mem_between m = true.
Theorem mem_between_1:
forall s,
mem_between s = true ->
exists x, In x s /\ above_low_bound x = true /\ below_high_bound x = true.
Theorem mem_between_2:
forall x s,
In x s -> above_low_bound x = true -> below_high_bound x = true ->
mem_between s = true.
Lemma raw_mem_between_1:
forall m,
raw_mem_between m = true ->
exists x, Raw.In x m /\ above_low_bound x = true /\ below_high_bound x = true.
Lemma raw_mem_between_2:
forall x m,
Raw.bst m ->
Raw.In x m -> above_low_bound x = true -> below_high_bound x = true ->
raw_mem_between m = true.
Theorem mem_between_1:
forall s,
mem_between s = true ->
exists x, In x s /\ above_low_bound x = true /\ below_high_bound x = true.
Theorem mem_between_2:
forall x s,
In x s -> above_low_bound x = true -> below_high_bound x = true ->
mem_between s = true.