(** Translation of [switch] statements *)
Inductive Rint: Z -> val -> Prop :=
| Rint_intro: forall n, Rint (Int.unsigned n) (Vint n).
Inductive Rlong: Z -> val -> Prop :=
| Rlong_intro: forall n, Rlong (Int64.unsigned n) (Vlong n).
Section SEL_SWITCH.
Variable make_cmp_eq: expr -> Z -> expr.
Variable make_cmp_ltu: expr -> Z -> expr.
Variable make_sub: expr -> Z -> expr.
Variable make_to_int: expr -> expr.
Variable modulus: Z.
Variable R: Z -> val -> Prop.
Hypothesis eval_make_cmp_eq: forall sp e m le a v i n,
eval_expr tge sp e m le a v -> R i v -> 0 <= n < modulus ->
eval_expr tge sp e m le (make_cmp_eq a n) (Val.of_bool (zeq i n)).
Hypothesis eval_make_cmp_ltu: forall sp e m le a v i n,
eval_expr tge sp e m le a v -> R i v -> 0 <= n < modulus ->
eval_expr tge sp e m le (make_cmp_ltu a n) (Val.of_bool (zlt i n)).
Hypothesis eval_make_sub: forall sp e m le a v i n,
eval_expr tge sp e m le a v -> R i v -> 0 <= n < modulus ->
exists v', eval_expr tge sp e m le (make_sub a n) v' /\ R ((i - n) mod modulus) v'.
Hypothesis eval_make_to_int: forall sp e m le a v i,
eval_expr tge sp e m le a v -> R i v ->
exists v', eval_expr tge sp e m le (make_to_int a) v' /\ Rint (i mod Int.modulus) v'.

(* Specifications: *)
Lemma sel_switch_correct_rec:
forall sp e m varg i x,
R i varg ->
forall t arg le,
wf_comptree modulus t ->
nth_error le arg = Some varg ->
comptree_match modulus i t = Some x ->
eval_exitexpr tge sp e m le (sel_switch make_cmp_eq make_cmp_ltu make_sub make_to_int arg t) x.
Lemma sel_switch_correct:
forall dfl cases arg sp e m varg i t le,
validate_switch modulus dfl cases t = true ->
eval_expr tge sp e m le arg varg ->
R i varg ->
0 <= i < modulus ->
eval_exitexpr tge sp e m le
(XElet arg (sel_switch make_cmp_eq make_cmp_ltu make_sub make_to_int O t))
(switch_target i dfl cases).