Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs. mk_varspecs prog. Defined.
Inductive tree :=
| LEAF: forall i, 0 <= i <= Int.max_signed -> tree
| NODE: tree -> tree -> tree.
Fixpoint treerep (t: tree) (p: val) : mpred :=
match t with
| LEAF i _ => !! (p = Vint (Int.repr (i+i+1))) && emp
| NODE t1 t2 => EX p1:val, EX p2: val,
data_at Tsh (Tstruct _tree noattr) (p1,p2) p
* treerep t1 p1 * treerep t2 p2
end.
Definition POINTER_BOUNDARY : Z := 1024.
Definition valid_int_or_ptr (x: val) :=
match x with
| Vint i => Int.testbit i 0 = true
\/ Int.unsigned i < POINTER_BOUNDARY
| Vptr b z => Ptrofs.testbit z 0 = false
| _ => False
end.
Hint Resolve treerep_local_facts : saturate_local.
Definition test_int_or_ptr_spec :=
DECLARE _test_int_or_ptr
WITH x : val
PRE [ _x OF int_or_ptr_type ]
PROP(valid_int_or_ptr x) LOCAL(temp _x x) SEP()
POST [ tint ]
PROP()
LOCAL(temp ret_temp
(Vint (Int.repr (match x with
| Vint _ => 1
| _ => 0
end))))
SEP().
Definition int_or_ptr_to_int_spec :=
DECLARE _int_or_ptr_to_int
WITH x : val
PRE [ _x OF int_or_ptr_type ]
PROP(is_int I32 Signed x) LOCAL(temp _x x) SEP()
POST [ tint ]
PROP() LOCAL (temp ret_temp x) SEP().
Definition int_or_ptr_to_ptr_spec :=
DECLARE _int_or_ptr_to_ptr
WITH x : val
PRE [ _x OF int_or_ptr_type ]
PROP(isptr x) LOCAL(temp _x x) SEP()
POST [ tptr tvoid ]
PROP() LOCAL (temp ret_temp x) SEP().
Definition int_to_int_or_ptr_spec :=
DECLARE _int_to_int_or_ptr
WITH x : val
PRE [ _x OF tint ]
PROP(valid_int_or_ptr x)
LOCAL(temp _x x) SEP()
POST [ int_or_ptr_type ]
PROP() LOCAL (temp ret_temp x) SEP().
Definition ptr_to_int_or_ptr_spec :=
DECLARE _ptr_to_int_or_ptr
WITH x : val
PRE [ _x OF tptr tvoid ]
PROP(valid_int_or_ptr x) LOCAL(temp _x x) SEP()
POST [ int_or_ptr_type ]
PROP() LOCAL (temp ret_temp x) SEP().
Definition makenode_spec :=
DECLARE _makenode
WITH p: val, q: val
PRE [ _left OF int_or_ptr_type, _right OF int_or_ptr_type ]
PROP() LOCAL(temp _left p; temp _right q) SEP()
POST [ tptr (Tstruct _tree noattr) ]
EX r:val,
PROP() LOCAL(temp ret_temp r)
SEP (data_at Tsh (Tstruct _tree noattr) (p,q) r).
Definition copytree_spec :=
DECLARE _copytree
WITH t: tree, p : val
PRE  [ _t OF int_or_ptr_type ]
PROP() LOCAL(temp _t p) SEP (treerep t p)
POST [ int_or_ptr_type ]
EX v:val,
PROP() LOCAL(temp ret_temp v)
SEP (treerep t p; treerep t v).
Definition Gprog : funspecs :=
ltac:(with_library prog [
test_int_or_ptr_spec;
int_or_ptr_to_int_spec;
int_or_ptr_to_ptr_spec;
int_to_int_or_ptr_spec;
ptr_to_int_or_ptr_spec;
makenode_spec; copytree_spec
]).

Lemma body_copytree: semax_body Vprog Gprog f_copytree copytree_spec.