Definition logical_and_result v1 t1 v2 t2 :=
match (strict_bool_val t1 v1) with
| Some b1 => if b1 then match (strict_bool_val t2 v2) with
| Some b2 => if b2 then  Vint Int.one
else Vint Int.zero
| None => Vundef end
else Vint Int.zero
| None => Vundef
end.
Definition logical_or_result v1 t1 v2 t2 :=
match (strict_bool_val t1 v1) with
| Some b1 => if b1 then Vint Int.one
else match (strict_bool_val t2 v2) with
| Some b2 => if b2 then  Vint Int.one
else Vint Int.zero
| None => Vundef end
| None => Vundef
end.
(* NOTE: In both logical_or and logical_and, compcert (up to 2.4) has (Etempvar tid tbool) where I conjecture that it should have (Etempvar tid tint). That means our lemmas here are incompatible with compcert, at the moment. *)
Definition logical_or tid e1 e2 :=
(Sifthenelse e1
(Sset tid (Econst_int (Int.repr 1) tint))
(Ssequence
(Sset tid (Ecast e2 tbool))
(Sset tid (Ecast (Etempvar tid tint (*tbool*)) tint)))).
Definition logical_and tid e1 e2 :=
(Sifthenelse e1
(Ssequence
(Sset tid (Ecast e2 tbool))
(Sset tid (Ecast (Etempvar tid tint (*tbool*)) tint)))
(Sset tid (Econst_int (Int.repr 0) tint))).

(* Specifications: *)
Lemma semax_pre_flipped :
forall (P' : environ -> mpred) (Espec : OracleKind) {cs: compspecs}
(Delta : tycontext) (P1 : list Prop) (P2 : list localdef)
(P3 : list mpred) (c : statement)
(R : ret_assert),
semax Delta P' c R ->
ENTAIL Delta, PROPx P1 (LOCALx P2 (SEPx P3)) |-- P' ->
semax Delta (PROPx P1 (LOCALx P2 (SEPx P3))) c R.
Lemma semax_while :
forall Espec {cs: compspecs} Delta Q test body (R: ret_assert),
bool_type (typeof test) = true ->
(local (tc_environ Delta) && Q |--  (tc_expr Delta (Eunop Cop.Onotbool test tint))) ->
(local (tc_environ Delta) && local (lift1 (typed_false (typeof test)) (eval_expr test)) && Q |-- RA_normal R) ->
@semax cs Espec Delta (local (`(typed_true (typeof test)) (eval_expr test)) && Q)  body (loop1_ret_assert Q R) ->
@semax cs Espec Delta Q (Swhile test body) R.
Lemma semax_while_3g1 :
forall Espec {cs: compspecs} {A} (v: A -> val) Delta P Q R test body Post,
bool_type (typeof test) = true ->
(forall a, ENTAIL Delta, PROPx (P a) (LOCALx (Q a) (SEPx (R a))) |-- (tc_expr Delta (Eunop Cop.Onotbool test tint))) ->
(forall a, ENTAIL Delta, PROPx (P a) (LOCALx (Q a) (SEPx (R a))) |-- local (`(eq (v a)) (eval_expr test))) ->
(forall a, @semax cs Espec Delta (PROPx (typed_true (typeof test) (v a) :: (P a)) (LOCALx (Q a) (SEPx (R a))))
body (loop1_ret_assert (EX a:A, PROPx (P a) (LOCALx (Q a) (SEPx (R a))))
(overridePost
(EX a:A, PROPx (typed_false (typeof test) (v a) :: P a)  (LOCALx (Q a) (SEPx (R a))))
Post))) ->
@semax cs Espec Delta (EX a:A, PROPx (P a) (LOCALx (Q a) (SEPx (R a))))
(Swhile test body)
(overridePost
(EX a:A, PROPx (typed_false (typeof test) (v a) :: P a)  (LOCALx (Q a) (SEPx (R a))))
Post).
Lemma semax_for_x :
forall Espec {cs: compspecs} Delta Q test body incr PreIncr Post,
bool_type (typeof test) = true ->
local (tc_environ Delta) && Q |-- (tc_expr Delta (Eunop Cop.Onotbool test tint)) ->
local (tc_environ Delta)
&& local (`(typed_false (typeof test)) (eval_expr test))
&& Q |-- RA_normal Post ->
@semax cs Espec Delta (local (`(typed_true (typeof test)) (eval_expr test)) && Q)
body (loop1_ret_assert PreIncr Post) ->
@semax cs Espec Delta PreIncr incr (normal_ret_assert Q) ->
@semax cs Espec Delta Q
(Sloop (Ssequence (Sifthenelse test Sskip Sbreak) body) incr)
Post.
Lemma semax_for :
forall Espec {cs: compspecs} {A:Type} (v: A -> val) Delta P Q R test body incr PreIncr Post,
bool_type (typeof test) = true ->
(forall a:A, ENTAIL Delta, PROPx (P a) (LOCALx (Q a) (SEPx (R a)))
|-- tc_expr Delta (Eunop Cop.Onotbool test tint)) ->
(forall a:A, ENTAIL Delta, PROPx (P a) (LOCALx (Q a) (SEPx (R a))) |--  local (`(eq (v a)) (eval_expr test))) ->
(forall a:A,
@semax cs Espec Delta (PROPx (typed_true (typeof test) (v a) :: P a) (LOCALx (Q a) (SEPx (R a))))
body (loop1_ret_assert (PreIncr a) Post)) ->
(forall a, @semax cs Espec Delta (PreIncr a) incr (normal_ret_assert (PROPx (P a) (LOCALx (Q a) (SEPx (R a)))))) ->
(forall a:A, ENTAIL Delta, PROPx (typed_false (typeof test) (v a) :: P a) (LOCALx (Q a) (SEPx (R a)))
|-- RA_normal Post) ->
@semax cs Espec Delta (EX a:A, PROPx (P a) (LOCALx (Q a) (SEPx (R a))))
(Sloop (Ssequence (Sifthenelse test Sskip Sbreak) body) incr)
Post.