(** Wrapping in a dependent type *)

Definition t := { h: R.heap | R.bst h }.(** Operations *)

Program Definition empty : t := R.Empty.Program Definition insert (x: E.t) (h: t) : t := R.insert x h.Program Definition findMin (h: t) : option E.t := R.findMin h.Program Definition deleteMin (h: t) : t := R.deleteMin h.Program Definition findMax (h: t) : option E.t := R.findMax h.Program Definition deleteMax (h: t) : t := R.deleteMax h.(** Membership (for specification) *)

Program Definition In (x: E.t) (h: t) : Prop := R.In x h.

(* Specifications: *)
Lemma In_empty: forall x, ~In x empty.
Lemma In_insert: forall x h y, In y (insert x h) <-> E.eq y x \/ In y h.
Lemma findMin_empty: forall h y, findMin h = None -> ~In y h.
Lemma findMin_min: forall h x y, findMin h = Some x -> In y h -> E.eq x y \/ E.lt x y.
Lemma In_deleteMin: forall h x y, findMin h = Some x -> (In y h <-> E.eq y x \/ In y (deleteMin h)).
Lemma findMax_empty: forall h y, findMax h = None -> ~In y h.
Lemma findMax_max: forall h x y, findMax h = Some x -> In y h -> E.eq y x \/ E.lt y x.
Lemma In_deleteMax: forall h x y, findMax h = Some x -> (In y h <-> E.eq y x \/ In y (deleteMax h)).
Lemma In_empty: forall x, ~In x empty.
Lemma In_insert: forall x h y, In y (insert x h) <-> E.eq y x \/ In y h.
Lemma findMin_empty: forall h y, findMin h = None -> ~In y h.
Lemma findMin_min: forall h x y, findMin h = Some x -> In y h -> E.eq x y \/ E.lt x y.
Lemma In_deleteMin: forall h x y, findMin h = Some x -> (In y h <-> E.eq y x \/ In y (deleteMin h)).
Lemma findMax_empty: forall h y, findMax h = None -> ~In y h.
Lemma findMax_max: forall h x y, findMax h = Some x -> In y h -> E.eq y x \/ E.lt y x.
Lemma In_deleteMax: forall h x y, findMax h = Some x -> (In y h <-> E.eq y x \/ In y (deleteMax h)).