(** Auxiliary for the compilation of [switch] statements. *)

Definition tr_jumptable (nexits: list node) (tbl: list nat) (ttbl: list node) : Prop :=
  forall v act,
  list_nth_z tbl v = Some act ->
  exists n, list_nth_z ttbl v = Some n /\ nth_error nexits act = Some n.

(* Specifications: *)
Lemma tr_move_incr: forall s1 s2, state_incr s1 s2 -> forall ns rs nd rd, tr_move s1.(st_code) ns rs nd rd -> tr_move s2.(st_code) ns rs nd rd.
Lemma tr_expr_incr: forall s1 s2, state_incr s1 s2 -> forall map pr a ns nd rd dst, tr_expr s1.(st_code) map pr a ns nd rd dst -> tr_expr s2.(st_code) map pr a ns nd rd dst with tr_condition_incr: forall s1 s2, state_incr s1 s2 -> forall map pr a ns ntrue nfalse, tr_condition s1.(st_code) map pr a ns ntrue nfalse -> tr_condition s2.(st_code) map pr a ns ntrue nfalse with tr_exprlist_incr: forall s1 s2, state_incr s1 s2 -> forall map pr al ns nd rl, tr_exprlist s1.(st_code) map pr al ns nd rl -> tr_exprlist s2.(st_code) map pr al ns nd rl.
Lemma add_move_charact: forall s ns rs nd rd s' i, add_move rs rd nd s = OK ns s' i -> tr_move s'.(st_code) ns rs nd rd.
Lemma transl_expr_charact: forall a map rd nd s ns s' pr INCR (TR: transl_expr map a rd nd s = OK ns s' INCR) (WF: map_valid map s) (OK: target_reg_ok map pr a rd) (VALID: regs_valid pr s) (VALID2: reg_valid rd s), tr_expr s'.(st_code) map pr a ns nd rd None with transl_exprlist_charact: forall al map rl nd s ns s' pr INCR (TR: transl_exprlist map al rl nd s = OK ns s' INCR) (WF: map_valid map s) (OK: target_regs_ok map pr al rl) (VALID1: regs_valid pr s) (VALID2: regs_valid rl s), tr_exprlist s'.(st_code) map pr al ns nd rl with transl_condexpr_charact: forall a map ntrue nfalse s ns s' pr INCR (TR: transl_condexpr map a ntrue nfalse s = OK ns s' INCR) (WF: map_valid map s) (VALID: regs_valid pr s), tr_condition s'.(st_code) map pr a ns ntrue nfalse.
Lemma transl_expr_assign_charact: forall id a map rd nd s ns s' INCR (TR: transl_expr map a rd nd s = OK ns s' INCR) (WF: map_valid map s) (OK: reg_map_ok map rd (Some id)), tr_expr s'.(st_code) map nil a ns nd rd (Some id).
Lemma alloc_optreg_map_ok: forall map optid s1 r s2 i, map_valid map s1 -> alloc_optreg map optid s1 = OK r s2 i -> reg_map_ok map r optid.
Lemma tr_switch_incr: forall s1 s2, state_incr s1 s2 -> forall map r nexits t ns, tr_switch s1.(st_code) map r nexits t ns -> tr_switch s2.(st_code) map r nexits t ns.
Lemma tr_stmt_incr: forall s1 s2, state_incr s1 s2 -> forall map s ns nd nexits ngoto nret rret, tr_stmt s1.(st_code) map s ns nd nexits ngoto nret rret -> tr_stmt s2.(st_code) map s ns nd nexits ngoto nret rret.
Lemma transl_exit_charact: forall nexits n s ne s' incr, transl_exit nexits n s = OK ne s' incr -> nth_error nexits n = Some ne /\ s' = s.
Lemma transl_jumptable_charact: forall nexits tbl s nl s' incr, transl_jumptable nexits tbl s = OK nl s' incr -> tr_jumptable nexits tbl nl /\ s' = s.
Lemma transl_switch_charact: forall map r nexits t s ns s' incr, map_valid map s -> reg_valid r s -> transl_switch r nexits t s = OK ns s' incr -> tr_switch s'.(st_code) map r nexits t ns.
Lemma transl_stmt_charact: forall map stmt nd nexits ngoto nret rret s ns s' INCR (TR: transl_stmt map stmt nd nexits ngoto nret rret s = OK ns s' INCR) (WF: map_valid map s) (OK: return_reg_ok s map rret), tr_stmt s'.(st_code) map stmt ns nd nexits ngoto nret rret.
Lemma transl_function_charact: forall f tf, transl_function f = Errors.OK tf -> tr_function f tf.