(*  This file demonstrates loop verifications using two advanced techniques: 1. Converting for-loop into while-loop 2. Peeling off the first iteration of a loop.  The function verified is this one, which computes integer square roots:  int f (int b) { int i, a; for (i=b+1; i*i>b; i--) { a=i; } return a; }  Notice that the variable [a] is uninitialized until the middle of the first iteration, _and_  it should be mentioned in the loop invariant.  How should this be handled? Let's see . . . *)
Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs.  mk_varspecs prog. Defined.
Definition f_spec : ident * funspec :=
DECLARE _f
WITH b: Z
PRE [ _a OF tint ]
PROP  (0 <= b; (b+1)*(b+1) < Int.max_signed)
LOCAL (temp _b (Vint (Int.repr b)))
SEP   ()
POST [ tuint ]
EX a:Z,
PROP ((a-1)*(a-1)<=b /\ a*a>b)
LOCAL(temp ret_temp  (Vint (Int.repr a)))
SEP ().
Definition Gprog : funspecs :=
ltac:(with_library prog [f_spec ]).

(* Specifications: *)
Lemma body_f: semax_body Vprog Gprog f_f f_spec.