Inductive return_inner_gen (S: list mpred): option val -> (environ -> mpred) -> (environ -> mpred) -> Prop :=
| return_inner_gen_main: forall ov_gen P ts u,
return_inner_gen S ov_gen (main_post P ts u) (PROPx nil (LOCALx nil (SEPx (TT :: S))))
| return_inner_gen_canon_nil':
forall ov_gen P R,
return_inner_gen S ov_gen
(PROPx P (LOCALx nil (SEPx R)))
(PROPx P (LOCALx nil (SEPx (R ++ S))))
| return_inner_gen_canon_Some':
forall P v R v_gen,
return_inner_gen S (Some v_gen)
(PROPx P (LOCALx (temp ret_temp v :: nil) (SEPx R)))
(PROPx (P ++ (v_gen = v) :: nil) (LOCALx nil (SEPx (R ++ S))))
| return_inner_gen_EX':
forall ov_gen (A: Type) (post1 post2: A -> environ -> mpred),
(forall a: A, return_inner_gen S ov_gen (post1 a) (post2 a)) ->
return_inner_gen S ov_gen (exp post1) (exp post2).

(* Specifications: *)
Lemma return_inner_gen_EX: forall S ov_gen A post1 post2,
(forall a: A, exists P, return_inner_gen S ov_gen (post1 a) P /\ post2 a = P) ->
return_inner_gen S ov_gen (exp post1) (exp post2).
Lemma return_inner_gen_canon_nil S: forall ov_gen P R Res,
PROPx P (LOCALx nil (SEPx (VST_floyd_app R S))) = Res ->
return_inner_gen S ov_gen (PROPx P (LOCALx nil (SEPx R))) Res.
Lemma return_inner_gen_canon_Some S: forall P v R v_gen Res,
PROPx (VST_floyd_app P ((v_gen = v) :: nil)) (LOCALx nil (SEPx (VST_floyd_app R S))) = Res ->
return_inner_gen S (Some v_gen) (PROPx P (LOCALx (temp ret_temp v :: nil) (SEPx R))) Res.
Lemma return_inner_gen_None_spec: forall S post1 post2,
return_inner_gen S None post1 post2 ->
post2 |-- (fun rho => post1 (make_args nil nil rho)) * SEPx S.
Lemma return_inner_gen_Some_spec: forall S v_gen post1 post2,
v_gen <> Vundef ->
return_inner_gen S (Some v_gen) post1 post2 ->
post2 |-- (fun rho => post1 (make_args (ret_temp :: nil) (v_gen :: nil) rho)) * SEPx S.
Lemma semax_return_None: forall {cs Espec} Delta Ppre Qpre Rpre Post1 sf SEPsf post2 post3,
ret_type Delta = Tvoid ->
return_outer_gen Post1 (frame_ret_assert (function_body_ret_assert (ret_type Delta) post2) sf) ->
ENTAIL Delta, PROPx Ppre (LOCALx Qpre (SEPx SEPsf)) |-- sf ->
return_inner_gen SEPsf None post2 post3 ->
ENTAIL Delta, PROPx Ppre (LOCALx Qpre (SEPx Rpre)) |-- post3 ->
@semax cs Espec Delta (PROPx Ppre (LOCALx Qpre (SEPx Rpre))) (Sreturn None) Post1.
Lemma semax_return_Some: forall {cs Espec} Delta Ppre Qpre Rpre Post1 sf SEPsf post2 post3 ret v_gen,
ENTAIL Delta, PROPx Ppre (LOCALx Qpre (SEPx Rpre)) |-- local (`(eq v_gen) (eval_expr (Ecast ret (ret_type Delta)))) ->
ENTAIL Delta, PROPx Ppre (LOCALx Qpre (SEPx Rpre)) |-- tc_expr Delta (Ecast ret (ret_type Delta)) ->
return_outer_gen Post1 (frame_ret_assert (function_body_ret_assert (ret_type Delta) post2) sf) ->
ENTAIL Delta, PROPx Ppre (LOCALx Qpre (SEPx SEPsf)) |-- sf ->
return_inner_gen SEPsf (Some v_gen) post2 post3 ->
ENTAIL Delta, PROPx Ppre (LOCALx Qpre (SEPx Rpre)) |-- post3 ->
@semax cs Espec Delta (PROPx Ppre (LOCALx Qpre (SEPx Rpre))) (Sreturn (Some ret)) Post1.
Lemma remove_PROP_LOCAL_left: forall P Q R S, R |-- S -> PROPx P (LOCALx Q R) |-- S.
Lemma remove_PROP_LOCAL_left':
forall P Q R S, `R |-- S ->
PROPx P (LOCALx Q (SEPx (R::nil))) |-- S.
Lemma SEP_nth_isolate:
forall n R Rn, nth_error R n = Some Rn ->
SEPx R = SEPx (Rn :: replace_nth n R emp).
Lemma nth_error_SEP_sepcon_TT: forall P Q R n Rn S,
PROPx P (LOCALx Q (SEPx (Rn :: nil))) |-- S ->
nth_error R n = Some Rn ->
PROPx P (LOCALx Q (SEPx R)) |-- S * TT.
Lemma SEP_replace_nth_isolate:
forall n R Rn Rn',
nth_error R n = Some Rn ->
SEPx (replace_nth n R Rn') = SEPx (Rn' :: replace_nth n R emp).
Lemma local_andp_lemma:
forall P Q, P |-- local Q -> P = local Q && P.
Lemma SEP_TT_right:
forall R, R |-- SEPx(TT::nil).
Lemma replace_nth_SEP: forall P Q R n Rn Rn', Rn |-- Rn' -> PROPx P (LOCALx Q (SEPx (replace_nth n R Rn))) |-- PROPx P (LOCALx Q (SEPx (replace_nth n R Rn'))).
Lemma replace_nth_SEP':
forall A P Q R n Rn Rn', local A && PROPx P (LOCALx Q (SEPx (Rn::nil))) |-- `Rn' ->
(local A && PROPx P (LOCALx Q (SEPx (replace_nth n R Rn)))) |-- (PROPx P (LOCALx Q (SEPx (replace_nth n R Rn')))).
Lemma nth_error_SEP_prop:
forall P Q R n (Rn: mpred) (Rn': Prop),
nth_error R n = Some Rn ->
Rn |-- !! Rn' ->
PROPx P (LOCALx Q (SEPx R)) |-- !! Rn'.
Lemma LOCAL_2_hd: forall P Q R Q1 Q2,
(PROPx P (LOCALx (Q1 :: Q2 :: Q) (SEPx R))) =
(PROPx P (LOCALx (Q2 :: Q1 :: Q) (SEPx R))).
Lemma lvar_eval_lvar {cs: compspecs}:
forall i t v rho, locald_denote (lvar i t v) rho -> eval_lvar i t rho = v.
Lemma lvar_eval_var:
forall i t v rho, locald_denote (lvar i t v) rho -> eval_var i t rho = v.
Lemma gvars_eval_var:
forall Delta gv i rho t, tc_environ Delta rho -> (var_types Delta) ! i = None -> locald_denote (gvars gv) rho -> eval_var i t rho = gv i.
Lemma lvar_isptr:
forall i t v rho, locald_denote (lvar i t v) rho -> isptr v.
Lemma gvars_isptr:
forall Delta gv i rho t, tc_environ Delta rho -> (glob_types Delta) ! i = Some t -> locald_denote (gvars gv) rho -> isptr (gv i).
Lemma lvar_isptr_eval_var :
forall i t v rho, locald_denote (lvar i t v) rho -> isptr (eval_var i t rho).