(** [env_equiv] is an equivalence relation between environments
  capturing the fact that two environments assign the same values to
  non-temporary registers, but can disagree on the values of temporary
  registers. *)

Definition env_equiv (e1 e2: env) : Prop :=
  forall r, is_not_temp r -> e1 r = e2 r.

(* Specifications: *)
Lemma env_equiv_refl: forall e, env_equiv e e.
Lemma env_equiv_refl': forall e1 e2, e1 = e2 -> env_equiv e1 e2.
Lemma env_equiv_sym: forall e1 e2, env_equiv e1 e2 -> env_equiv e2 e1.
Lemma env_equiv_trans: forall e1 e2 e3, env_equiv e1 e2 -> env_equiv e2 e3 -> env_equiv e1 e3.
Lemma exec_par_env_equiv: forall m e1 e2, move_no_temp m -> env_equiv e1 e2 -> env_equiv (exec_par m e1) (exec_par m e2).
Lemma transition_preserves_semantics: forall st st' e, transition st st' -> state_wf st -> env_equiv (statemove st' e) (statemove st e).
Lemma transitions_preserve_semantics: forall st st' e, transitions st st' -> state_wf st -> env_equiv (statemove st' e) (statemove st e).
Lemma state_wf_start: forall mu, move_no_temp mu -> is_mill mu -> state_wf (State mu nil nil).
Theorem transitions_correctness: forall mu tau, move_no_temp mu -> is_mill mu -> transitions (State mu nil nil) (State nil nil tau) -> forall e, env_equiv (exec_seq (List.rev tau) e) (exec_par mu e).