Hint Resolve tree_rep_nullval: saturate_local.

(* Specifications: *)
Lemma treebox_rep_leaf: forall x p b (v: val),
is_pointer_or_null v ->
Int.min_signed <= Z.of_nat x <= Int.max_signed ->
data_at Tsh t_struct_tree (Vint (Int.repr (Z.of_nat x)), (v, (nullval, nullval))) p * data_at Tsh (tptr t_struct_tree) p b |-- treebox_rep (T E x v E) b.
Lemma treebox_rep_internal: forall l x v r b p,
Int.min_signed <= Z.of_nat x <= Int.max_signed ->
tc_val (tptr Tvoid) v ->
data_at Tsh (tptr t_struct_tree) p b *
field_at Tsh t_struct_tree [StructField _key] (Vint (Int.repr (Z.of_nat x))) p *
field_at Tsh t_struct_tree [StructField _value] v p *
treebox_rep l (field_address t_struct_tree [StructField _left] p) *
treebox_rep r (field_address t_struct_tree [StructField _right] p) |--
treebox_rep (T l x v r) b.
Lemma tree_rep_internal: forall l x v r (p p1 p2: val),
Int.min_signed <= Z.of_nat x <= Int.max_signed ->
tc_val (tptr Tvoid) v ->
data_at Tsh t_struct_tree (Vint (Int.repr (Z.of_nat x)), (v, (p1, p2))) p *
tree_rep l p1 *
tree_rep r p2 |--
tree_rep (T l x v r) p.
Lemma is_pointer_or_null_force_val_sem_cast_neutral: forall p,
is_pointer_or_null p -> force_val (sem_cast_neutral p) = p.
Lemma treebox_rep_leaf: forall x p b (v: val),
is_pointer_or_null v ->
Int.min_signed <= x <= Int.max_signed ->
field_at Tsh t_struct_tree [] (Vint (Int.repr x), (v, (nullval, nullval))) p *
field_at Tsh (tptr t_struct_tree) [] p b |-- treebox_rep (T E x v E) b.
(* Lemma bst_left_entail: forall (t1 t1' t2: tree val) k (v p1 p2 p b: val), Int.min_signed <= k <= Int.max_signed -> is_pointer_or_null v -> data_at Tsh (tptr t_struct_tree) p b * data_at Tsh t_struct_tree (Vint (Int.repr k), (v, (p1, p2))) p * tree_rep t1 p1 * tree_rep t2 p2 |-- treebox_rep t1 (field_address t_struct_tree [StructField _left] p) * (treebox_rep t1' (field_address t_struct_tree [StructField _left] p) -* treebox_rep (T t1' k v t2) b).  Lemma bst_right_entail: forall (t1 t2 t2': tree val) k (v p1 p2 p b: val), Int.min_signed <= k <= Int.max_signed -> is_pointer_or_null v -> data_at Tsh (tptr t_struct_tree) p b * data_at Tsh t_struct_tree (Vint (Int.repr k), (v, (p1, p2))) p * tree_rep t1 p1 * tree_rep t2 p2 |-- treebox_rep t2 (field_address t_struct_tree [StructField _right] p) * (treebox_rep t2' (field_address t_struct_tree [StructField _right] p) -* treebox_rep (T t1 k v t2') b).  Lemma modus_ponens_wand' {A}{ND: NatDed A}{SL: SepLog A}: forall P Q R: A, P |-- Q -> P * (Q -* R) |-- R. *)
Lemma if_trueb: forall {A: Type} b (a1 a2: A), b = true -> (if b then a1 else a2) = a1.
Definition lookup_inv (b0 p0: val) (t0: tree val) (x: Z): environ -> mpred :=
EX p: val, EX t: tree val,
PROP(lookup nullval x t = lookup nullval x t0)
LOCAL(temp _p p; temp _x (Vint (Int.repr x)))
SEP(tree_rep t p;  (tree_rep t p -* tree_rep t0 p0)).
Lemma body_lookup: semax_body Vprog Gprog f_lookup lookup_spec.
Lemma body_turn_left: semax_body Vprog Gprog f_turn_left turn_left_spec.
Definition pushdown_left_inv (b_res: val) (t_res: tree val): environ -> mpred :=
EX b: val, EX ta: tree val, EX x: Z, EX v: val, EX tb: tree val,
PROP  ()
LOCAL (temp _t b)
SEP   (treebox_rep (T ta x v tb) b;
(treebox_rep (pushdown_left ta tb) b -* treebox_rep t_res b_res)).
Lemma body_pushdown_left: semax_body Vprog Gprog f_pushdown_left pushdown_left_spec.
Lemma treebox_rep_leaf: forall x p b (v: val),
is_pointer_or_null v ->
Int.min_signed <= x <= Int.max_signed ->
data_at Tsh t_struct_tree (Vint (Int.repr x), (v, (nullval, nullval))) p * data_at Tsh (tptr t_struct_tree) p b |-- treebox_rep (T E x v E) b.
Lemma bst_left_entail: forall (t1 t1' t2: tree val) k (v p1 p2 p b: val),
Int.min_signed <= k <= Int.max_signed ->
is_pointer_or_null v ->
data_at Tsh (tptr t_struct_tree) p b *
data_at Tsh t_struct_tree (Vint (Int.repr k), (v, (p1, p2))) p *
tree_rep t1 p1 * tree_rep t2 p2
|-- treebox_rep t1 (field_address t_struct_tree [StructField _left] p) *
(treebox_rep t1'
(field_address t_struct_tree [StructField _left] p) -*
treebox_rep (T t1' k v t2) b).
Lemma bst_right_entail: forall (t1 t2 t2': tree val) k (v p1 p2 p b: val),
Int.min_signed <= k <= Int.max_signed ->
is_pointer_or_null v ->
data_at Tsh (tptr t_struct_tree) p b *
data_at Tsh t_struct_tree (Vint (Int.repr k), (v, (p1, p2))) p *
tree_rep t1 p1 * tree_rep t2 p2
|-- treebox_rep t2 (field_address t_struct_tree [StructField _right] p) *
(treebox_rep t2'
(field_address t_struct_tree [StructField _right] p) -*
treebox_rep (T t1 k v t2') b).
Lemma modus_ponens_wand' {A}{ND: NatDed A}{SL: SepLog A}:
forall P Q R: A, P |-- Q -> P * (Q -* R) |-- R.
Lemma if_trueb: forall {A: Type} b (a1 a2: A), b = true -> (if b then a1 else a2) = a1.
Definition lookup_inv (b0 p0: val) (t0: tree val) (x: Z): environ -> mpred :=
EX p: val, EX t: tree val,
PROP(lookup nullval x t = lookup nullval x t0)
LOCAL(temp _p p; temp _x (Vint (Int.repr x)))
SEP(tree_rep t p;  (tree_rep t p -* tree_rep t0 p0)).
Lemma body_lookup: semax_body Vprog Gprog f_lookup lookup_spec.
Lemma body_turn_left: semax_body Vprog Gprog f_turn_left turn_left_spec.
Definition pushdown_left_inv (b_res: val) (t_res: tree val): environ -> mpred :=
EX b: val, EX ta: tree val, EX x: Z, EX v: val, EX tb: tree val,
PROP  ()
LOCAL (temp _t b)
SEP   (treebox_rep (T ta x v tb) b;
(treebox_rep (pushdown_left ta tb) b -* treebox_rep t_res b_res)).
Lemma cancel_emp_spacer:
forall sh x y p, x=y ->
emp |-- spacer sh x y p.
Lemma cancel_spacer_emp:
forall sh x y p, x=y ->
spacer sh x y p |-- emp.
Lemma body_pushdown_left: semax_body Vprog Gprog f_pushdown_left pushdown_left_spec.
Definition delete_inv (b0: val) (t0: tree val) (x: Z): environ -> mpred :=
EX b: val, EX t: tree val,
PROP()
LOCAL(temp _t b; temp _x (Vint (Int.repr x)))
SEP(treebox_rep t b;  (treebox_rep (delete x t) b -* treebox_rep (delete x t0) b0)).
Lemma body_delete: semax_body Vprog Gprog f_delete delete_spec.
Lemma body_treebox_new: semax_body Vprog Gprog f_treebox_new treebox_new_spec.
Lemma body_tree_free: semax_body Vprog Gprog f_tree_free tree_free_spec.
Lemma body_treebox_free: semax_body Vprog Gprog f_treebox_free treebox_free_spec.
Module Abstractions.