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 modulo_samerepr: forall x y, Z.modulo x Int.modulus = Z.modulo y Int.modulus -> Int.repr x = Int.repr y.
Lemma select_switch_case_signed: forall y n x c sl, Z.modulo x Int.modulus = Z.modulo y Int.modulus -> 0 <= x < Int.modulus -> select_switch_case n (LScons (Some x) c sl) = if zeq (Int.unsigned (Int.repr y)) n then Some (LScons (Some x) c sl) else select_switch_case n sl.