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))).

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).