Section Sfor.
Context {cs : compspecs}
(Delta: tycontext)
(_i: ident)
(m n: Z)
(init: statement)
(hi: expr)
(inv0: environ -> mpred)
(assert_callee inv1 inv2: Z -> environ -> mpred)
(type_i: type)
(int_min int_max: Z).
Hypothesis EVAL_hi: ENTAIL Delta, inv0 |-- EX n': val, !! (Int6432_val (typeof hi) n' n) && local (` (eq n') (eval_expr hi)).
Hypothesis TC_hi: ENTAIL Delta, inv0 |-- tc_expr Delta hi.
Hypothesis I32_i: is_int32_type type_i = true.
Hypothesis IMM: int_type_min_max type_i (typeof hi) = Some (int_min, int_max).
Hypothesis Range_m: int_min <= m <= int_max.
Hypothesis Range_n: int_min <= n <= int_max.
Hypothesis TI: (temp_types Delta) ! _i = Some type_i.
Hypothesis EQ_inv1: forall i : Z, local (locald_denote (temp _i (Vint (Int.repr i)))) && assert_callee i = inv1 i.
Hypothesis EQ_inv0: (EX i : Z, !! (m <= i <= n) && inv1 i)%assert = inv0.
Hypothesis EQ_inv2: forall i, local (locald_denote (temp _i (Vint (Int.repr i)))) && assert_callee (i+1) = inv2 i.
Hypothesis SUBST_callee: forall v i, subst _i (`v) (assert_callee i) = assert_callee i.
End Sfor.

Lemma semax_for :
forall (Inv: environ->mpred) (n: Z) Espec {cs: compspecs} Delta
(Pre: environ->mpred)
(_i: ident) (init: statement) (m: Z) (hi: expr) (body MORE_COMMAND: statement) (Post: ret_assert)
(type_i: type)
(assert_callee: Z -> environ -> mpred)
(inv0: environ -> mpred)
(inv1 inv2: Z -> environ -> mpred) s
(TI: (temp_types Delta) ! _i = Some type_i)
(CALLEE: Inv = exp assert_callee)
(INV: Sfor_inv Delta _i m hi n assert_callee inv0 inv1 inv2)
(SETUP: Sfor_setup Delta _i Pre init hi type_i m n assert_callee inv0),
(forall i, m <= i < n ->
@semax cs Espec Delta (inv1 i)
body
(for_ret_assert (inv2 i) Post)) ->
@semax cs Espec Delta
(inv1 n) MORE_COMMAND Post ->
@semax cs Espec Delta Pre
(Ssequence
(Sfor init
(Ebinop Olt (Etempvar _i type_i) hi (Tint I32 Signed noattr))
body
(Sset _i (Ebinop Oadd (Etempvar _i type_i) (Econst_int (Int.repr 1) (Tint I32 s noattr)) type_i)))
MORE_COMMAND) Post.