Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs. mk_varspecs prog. Defined.
Definition reverse_spec :=
DECLARE _reverse
WITH a0: val, sh : share, contents : list int, size: Z
PRE [ _a OF (tptr tint), _n OF tint ]
PROP (0 <= size <= Int.max_signed; writable_share sh)
LOCAL (temp _a a0; temp _n (Vint (Int.repr size)))
SEP (data_at sh (tarray tint size) (map Vint contents) a0)
POST [ tvoid ]
PROP() LOCAL()
SEP(data_at sh (tarray tint size) (map Vint (rev contents)) a0).
Definition main_spec :=
DECLARE _main
WITH gv : globals
PRE  [] main_pre prog tt nil gv
POST [ tint ] main_post prog nil gv.
Definition Gprog : funspecs :=   ltac:(with_library prog [reverse_spec; main_spec]).
Definition flip_ends {A} lo hi (contents: list A) :=
sublist 0 lo (rev contents)
++ sublist lo hi contents
++ sublist hi (Zlength contents) (rev contents).
Definition reverse_Inv a0 sh contents size :=
(EX j:Z,
(PROP  (0 <= j; j <= size-j)
LOCAL  (temp _a a0; temp _lo (Vint (Int.repr j)); temp _hi (Vint (Int.repr (size-j))))
SEP (data_at sh (tarray tint size) (flip_ends j (size-j) contents) a0)))%assert.
Hint Rewrite @Zlength_flip_ends using (autorewrite with sublist; omega) : sublist.

Lemma body_reverse: semax_body Vprog Gprog f_reverse reverse_spec.