(** A compilation environment (mapping) is valid in a given state if
  the registers associated with Cminor local variables and let-bound variables
  are valid in the state. *)

Definition map_valid (m: mapping) (s: state) : Prop :=
  forall r, reg_in_map m r -> reg_valid r s.

(* Specifications: *)
Lemma map_valid_incr: forall s1 s2 m, state_incr s1 s2 -> map_valid m s1 -> map_valid m s2.
Lemma new_reg_valid: forall s1 s2 r i, new_reg s1 = OK r s2 i -> reg_valid r s2.
Lemma new_reg_fresh: forall s1 s2 r i, new_reg s1 = OK r s2 i -> reg_fresh r s1.
Lemma new_reg_not_in_map: forall s1 s2 m r i, new_reg s1 = OK r s2 i -> map_valid m s1 -> ~(reg_in_map m r).
Lemma init_mapping_valid: forall s, map_valid init_mapping s.
Lemma find_var_in_map: forall s1 s2 map name r i, find_var map name s1 = OK r s2 i -> reg_in_map map r.
Lemma find_var_valid: forall s1 s2 map name r i, find_var map name s1 = OK r s2 i -> map_valid map s1 -> reg_valid r s1.
Lemma find_letvar_in_map: forall s1 s2 map idx r i, find_letvar map idx s1 = OK r s2 i -> reg_in_map map r.
Lemma find_letvar_valid: forall s1 s2 map idx r i, find_letvar map idx s1 = OK r s2 i -> map_valid map s1 -> reg_valid r s1.
Lemma add_var_valid: forall s1 s2 map1 map2 name r i, add_var map1 name s1 = OK (r, map2) s2 i -> map_valid map1 s1 -> reg_valid r s2 /\ map_valid map2 s2.
Lemma add_vars_valid: forall namel s1 s2 map1 map2 rl i, add_vars map1 namel s1 = OK (rl, map2) s2 i -> map_valid map1 s1 -> regs_valid rl s2 /\ map_valid map2 s2.
Lemma add_var_letenv: forall map1 id s1 r map2 s2 i, add_var map1 id s1 = OK (r, map2) s2 i -> map2.(map_letvars) = map1.(map_letvars).
Lemma add_vars_letenv: forall il map1 s1 rl map2 s2 i, add_vars map1 il s1 = OK (rl, map2) s2 i -> map2.(map_letvars) = map1.(map_letvars).
Lemma add_letvar_valid: forall map s r, map_valid map s -> reg_valid r s -> map_valid (add_letvar map r) s.
Lemma alloc_reg_valid: forall a s1 s2 map r i, map_valid map s1 -> alloc_reg map a s1 = OK r s2 i -> reg_valid r s2.
Lemma alloc_reg_fresh_or_in_map: forall map a s r s' i, map_valid map s -> alloc_reg map a s = OK r s' i -> reg_in_map map r \/ reg_fresh r s.
Lemma alloc_regs_valid: forall al s1 s2 map rl i, map_valid map s1 -> alloc_regs map al s1 = OK rl s2 i -> regs_valid rl s2.
Lemma alloc_regs_fresh_or_in_map: forall map al s rl s' i, map_valid map s -> alloc_regs map al s = OK rl s' i -> forall r, In r rl -> reg_in_map map r \/ reg_fresh r s.
Lemma alloc_optreg_valid: forall dest s1 s2 map r i, map_valid map s1 -> alloc_optreg map dest s1 = OK r s2 i -> reg_valid r s2.
Lemma alloc_optreg_fresh_or_in_map: forall map dest s r s' i, map_valid map s -> alloc_optreg map dest s = OK r s' i -> reg_in_map map r \/ reg_fresh r s.