(* This file illustrates two approaches to C verification, described in Section III of this paper:  Modular Verification for Computer Security, by Andrew W. Appel, in IEEE Computer Security Foundations conference (CSF'16), June 2016. http://www.cs.princeton.edu/~appel/papers/modsec.pdf *)
Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs.  mk_varspecs prog. Defined.
Open Scope Z.
Hint Extern 3 (is_int I32 _ (Znth _ (map Vint _))) =>
(apply  is_int_I32_Znth_map_Vint; rewrite ?Zlength_map; omega) : core.
Definition minimum_spec :=
DECLARE _minimum
WITH a: val, n: Z, al: list Z
PRE [ _a OF tptr tint , _n OF tint ]
PROP  (1 <= n <= Int.max_signed; Forall repable_signed al)
LOCAL (temp _a a; temp _n (Vint (Int.repr n)))
SEP   (data_at Ews (tarray tint n) (map Vint (map Int.repr al)) a)
POST [ tint ]
PROP ()
LOCAL(temp ret_temp  (Vint (Int.repr (fold_right Z.min (hd 0 al) al))))
SEP   (data_at Ews (tarray tint n) (map Vint (map Int.repr al)) a).
Definition Gprog : funspecs :=
ltac:(with_library prog [minimum_spec]).

(* First approach from "Modular Verification for Computer Security", proved using forward_for_simple_bound *)
Lemma body_min: semax_body Vprog Gprog f_minimum minimum_spec.