Section TREE_ABS.
Definition total_map (A:Type) := key -> A.
Definition t_empty {A:Type} (v : A) : total_map A :=
(fun _ => v).
Definition t_update {A:Type} (m : total_map A)
(x : key) (v : A) :=
fun x' => if x =? x' then v else m x'.
Definition combine {A} (pivot: key) (m1 m2: total_map A) : total_map A :=
fun x : key => if zlt x pivot  then m1 x else m2 x.
Inductive Abs:  tree val -> total_map val -> Prop :=
| Abs_E: Abs E (t_empty nullval)
| Abs_T: forall a b l k v r,
Abs l a ->
Abs r b ->
Abs (T l k v r)  (t_update (combine k a b) k v).
Admitted.  (* This is an exercise in Verified Functional Algorithms *)
Admitted.  (* This is an exercise in Verified Functional Algorithms *)
Definition tmap_rep (m: total_map val) (p: val) : mpred :=
EX t: tree val, !! Abs t m && treebox_rep t p.
Definition abs_insert_spec :=
DECLARE _insert
WITH b: val, x: Z, v: val, m: total_map val
PRE  [ _t OF (tptr (tptr t_struct_tree)), _x OF tint,
_value OF (tptr Tvoid)   ]
PROP( Int.min_signed <= x <= Int.max_signed; is_pointer_or_null v)
LOCAL(temp _t b; temp _x (Vint (Int.repr x)); temp _value v)
SEP (tmap_rep m b)
POST [ Tvoid ]
PROP()
LOCAL()
SEP (tmap_rep (t_update m x v) b).
Definition abs_treebox_new_spec :=
DECLARE _treebox_new
WITH u : unit
PRE  [  ]
PROP() LOCAL() SEP ()
POST [ tptr (tptr t_struct_tree) ]
EX v:val,
PROP()
LOCAL(temp ret_temp v)
SEP (tmap_rep (t_empty nullval) v).
Definition abs_treebox_free_spec :=
DECLARE _treebox_free
WITH m: total_map val, p: val
PRE  [ _b OF (tptr (tptr t_struct_tree)) ]
PROP() LOCAL(temp _b p) SEP (tmap_rep m p)
POST [ Tvoid ]
PROP()
LOCAL()
SEP (emp).
Definition main_spec :=
DECLARE _main
WITH gv : globals
PRE  [] main_pre prog tt nil gv
POST [ tint ] main_post prog nil gv.

Lemma subsume_insert:
funspec_sub (snd insert_spec) (snd abs_insert_spec).