Definition mallocN_spec :=
DECLARE _mallocN
WITH n: Z
PRE [ 1%positive OF tint]
PROP (4 <= n <= Int.max_unsigned)
LOCAL (temp 1%positive (Vint (Int.repr n)))
SEP ()
POST [ tptr tvoid ]
EX v: val,
PROP (malloc_compatible n v)
LOCAL (temp ret_temp v)
SEP (memory_block Tsh n v).
Definition freeN_spec :=
DECLARE _freeN
WITH p : val , n : Z
PRE [ 1%positive OF tptr tvoid , 2%positive OF tint]
(* we should also require natural_align_compatible (eval_id 1) *)
PROP() LOCAL (temp 1%positive p; temp 2%positive (Vint (Int.repr n)))
SEP (memory_block Tsh n p)
POST [ tvoid ]
PROP () LOCAL () SEP ().
Definition 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 (data_at Tsh (tptr t_struct_tree) nullval v).
Definition insert_spec :=
DECLARE _insert
WITH b: val, x: Z, v: val, t: tree 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 (treebox_rep t b)
POST [ Tvoid ]
PROP()
LOCAL()
SEP (treebox_rep (insert x v t) b).
Definition lookup_spec :=
DECLARE _lookup
WITH b: val, x: Z, v: val, t: tree val
PRE  [ _t OF (tptr (tptr t_struct_tree)), _x OF tint  ]
PROP( Int.min_signed <= x <= Int.max_signed)
LOCAL(temp _t b; temp _x (Vint (Int.repr x)))
SEP (treebox_rep t b)
POST [ tptr Tvoid ]
PROP()
LOCAL(temp ret_temp (lookup nullval x t))
SEP (treebox_rep t b).
Definition turn_left_spec :=
DECLARE _turn_left
WITH ta: tree val, x: Z, vx: val, tb: tree val, y: Z, vy: val, tc: tree val, b: val, l: val, pa: val, r: val
PRE  [ __l OF (tptr (tptr (Tstruct _tree noattr))),
_l OF (tptr (Tstruct _tree noattr)),
_r OF (tptr (Tstruct _tree noattr))]
PROP(Int.min_signed <= x <= Int.max_signed; is_pointer_or_null vx)
LOCAL(temp __l b; temp _l l; temp _r r)
SEP (data_at Tsh (tptr t_struct_tree) l b;
data_at Tsh t_struct_tree (Vint (Int.repr x), (vx, (pa, r))) l;
tree_rep ta pa;
tree_rep (T tb y vy tc) r)
POST [ Tvoid ]
EX pc: val,
PROP(Int.min_signed <= y <= Int.max_signed; is_pointer_or_null vy)
LOCAL()
SEP (data_at Tsh (tptr t_struct_tree) r b;
data_at Tsh t_struct_tree (Vint (Int.repr y), (vy, (l, pc))) r;
tree_rep (T ta x vx tb) l;
tree_rep tc pc).
Definition pushdown_left_spec :=
DECLARE _pushdown_left
WITH ta: tree val, x: Z, v: val, tb: tree val, b: val, p: val
PRE  [ _t OF (tptr (tptr (Tstruct _tree noattr)))]
PROP(Int.min_signed <= x <= Int.max_signed; tc_val (tptr Tvoid) v)
LOCAL(temp _t b)
SEP (data_at Tsh (tptr t_struct_tree) p b;
field_at Tsh t_struct_tree [StructField _key] (Vint (Int.repr x)) p;
field_at Tsh t_struct_tree [StructField _value] v p;
treebox_rep ta (field_address t_struct_tree [StructField _left] p);
treebox_rep tb (field_address t_struct_tree [StructField _right] p))
POST [ Tvoid ]
PROP()
LOCAL()
SEP (treebox_rep (pushdown_left ta tb) b).
Definition delete_spec :=
DECLARE _delete
WITH b: val, x: Z, t: tree val
PRE  [ _t OF (tptr (tptr t_struct_tree)), _x OF tint]
PROP( Int.min_signed <= x <= Int.max_signed)
LOCAL(temp _t b; temp _x (Vint (Int.repr x)))
SEP (treebox_rep t b)
POST [ Tvoid ]
PROP()
LOCAL()
SEP (treebox_rep (delete x t) b).
Definition tree_free_spec :=
DECLARE _tree_free
WITH t: tree val, p: val
PRE  [ _p OF (tptr t_struct_tree) ]
PROP() LOCAL(temp _p p) SEP (tree_rep t p)
POST [ Tvoid ]
PROP()
LOCAL()
SEP (emp).
Definition treebox_free_spec :=
DECLARE _treebox_free
WITH t: tree val, b: val
PRE  [ _b OF (tptr (tptr t_struct_tree)) ]
PROP() LOCAL(temp _b b) SEP (treebox_rep t b)
POST [ Tvoid ]
PROP()
LOCAL()
SEP (emp).
Definition Gprog : funspecs :=
ltac:(with_library prog [
mallocN_spec; freeN_spec; treebox_new_spec;
tree_free_spec; treebox_free_spec;
insert_spec; lookup_spec;
turn_left_spec; pushdown_left_spec; delete_spec
]).

Lemma tree_rep_saturate_local:
forall t p, tree_rep t p |-- !! is_pointer_or_null p.