Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs. mk_varspecs prog. Defined.
Definition tlist := Tstruct _list noattr.
Definition tpile := Tstruct _pile noattr.
Fixpoint listrep (sigma: list Z) (x: val) : mpred :=
match sigma with
| h::hs =>
EX y:val,
!! (0 <= h <=  Int.max_signed) &&
data_at Ews tlist (Vint (Int.repr h), y) x
* malloc_token Ews tlist x
*  listrep hs y
| nil =>
!! (x = nullval) && emp
end.
Hint Resolve listrep_local_facts : saturate_local.
Hint Resolve listrep_valid_pointer : valid_pointer.
Definition pilerep (sigma: list Z) (p: val) : mpred :=
EX x:val, data_at Ews tpile x p
* listrep sigma x.
Definition pile_freeable (p: val) : mpred :=
malloc_token Ews tpile p.
Hint Resolve pilerep_local_facts : saturate_local.
Hint Resolve pilerep_valid_pointer : valid_pointer.
Local Open Scope assert.
Definition surely_malloc_spec :=
DECLARE _surely_malloc
WITH t:type, gv: globals
PRE [ _n OF tuint ]
PROP (0 <= sizeof t <= Int.max_unsigned;
complete_legal_cosu_type t = true;
natural_aligned natural_alignment t = true)
LOCAL (temp _n (Vint (Int.repr (sizeof t))); gvars gv)
SEP (mem_mgr gv)
POST [ tptr tvoid ] EX p:_,
PROP ()
LOCAL (temp ret_temp p)
SEP (mem_mgr gv; malloc_token Ews t p * data_at_ Ews t p).
Definition Pile_new_spec :=
DECLARE _Pile_new
WITH gv: globals
PRE [ ] PROP() LOCAL(gvars gv) SEP(mem_mgr gv)
POST[ tptr tpile ]
EX p: val,
PROP() LOCAL(temp ret_temp p)
SEP(pilerep nil p; pile_freeable p; mem_mgr gv).
Definition Pile_add_spec :=
DECLARE _Pile_add
WITH p: val, n: Z, sigma: list Z, gv: globals
PRE [ _p OF tptr tpile, _n OF tint  ]
PROP(0 <= n <= Int.max_signed)
LOCAL(temp _p p; temp _n (Vint (Int.repr n)); gvars gv)
SEP(pilerep sigma p; mem_mgr gv)
POST[ tvoid ]
PROP() LOCAL()
SEP(pilerep (n::sigma) p; mem_mgr gv).
Definition sumlist : list Z -> Z := List.fold_right Z.add 0.
Definition Pile_count_spec :=
DECLARE _Pile_count
WITH p: val, sigma: list Z
PRE [ _p OF tptr tpile  ]
PROP(0 <= sumlist sigma <= Int.max_signed)
LOCAL(temp _p p)
SEP(pilerep sigma p)
POST[ tint ]
PROP()
LOCAL(temp ret_temp (Vint (Int.repr (sumlist sigma))))
SEP(pilerep sigma p).
Definition Pile_free_spec :=
DECLARE _Pile_free
WITH p: val, sigma: list Z, gv: globals
PRE [ _p OF tptr tpile  ]
PROP()
LOCAL(temp _p p; gvars gv)
SEP(pilerep sigma p; pile_freeable p; mem_mgr gv)
POST[ tvoid ]
PROP() LOCAL() SEP(mem_mgr gv).
Definition ispecs := [surely_malloc_spec].
Definition specs := [Pile_new_spec; Pile_add_spec; Pile_count_spec; Pile_free_spec].

(*Clients -- apile.v and onepile.v -- also need these lemmas:*)
Lemma pile_new_aux gx x ret:
(EX p : val, PROP ( )  LOCAL (temp ret_temp p)  SEP (pilerep [] p; pile_freeable p; mem_mgr x))%assert (make_ext_rval gx ret)
|-- !! is_pointer_or_null (force_val ret).