(** ** Transitions preserve semantics *)
(** We define the semantics of states as follows. For a triple [mu, sigma, tau], we perform the moves [tau] in reverse sequential order, then the moves [mu ++ sigma] in parallel. *)
Definition statemove (st: state) (e: env) :=
match st with
| State mu sigma tau => exec_par (mu ++ sigma) (exec_seq_rev tau e)
end.
(** In preparation to showing that transitions preserve semantics, we prove various properties of the parallel and sequential interpretations of moves. *)

(* Specifications: *)
Lemma exec_par_outside:
forall m e r, ~In r (dests m) -> exec_par m e r = e r.
Lemma exec_par_lift:
forall m1 s d m2 e,
~In d (dests m1) ->
exec_par (m1 ++ (s, d) :: m2) e = exec_par ((s, d) :: m1 ++ m2) e.
Lemma exec_par_ident:
forall m1 r m2 e,
is_mill (m1 ++ (r, r) :: m2) ->
exec_par (m1 ++ (r, r) :: m2) e = exec_par (m1 ++ m2) e.
Lemma exec_seq_app:
forall m1 m2 e,
exec_seq (m1 ++ m2) e = exec_seq m2 (exec_seq m1 e).
Lemma exec_seq_rev_app:
forall m1 m2 e,
exec_seq_rev (m1 ++ m2) e = exec_seq_rev m1 (exec_seq_rev m2 e).
Lemma exec_seq_exec_seq_rev:
forall m e,
exec_seq_rev m e = exec_seq (List.rev m) e.
Lemma exec_seq_rev_exec_seq:
forall m e,
exec_seq m e = exec_seq_rev (List.rev m) e.
Lemma exec_par_update_no_read:
forall s d m e,
no_read m d ->
~In d (dests m) ->
exec_par m (update d (e s) e) =
update d (e s) (exec_par m e).
Lemma exec_par_append_eq:
forall m1 m2 m3 e2 e3,
exec_par m2 e2 = exec_par m3 e3 ->
(forall r, In r (srcs m1) -> e2 r = e3 r) ->
exec_par (m1 ++ m2) e2 = exec_par (m1 ++ m3) e3.
Lemma exec_par_combine:
forall e sl dl,
List.length sl = List.length dl ->
list_norepet dl ->
let e' := exec_par (combine sl dl) e in
List.map e' dl = List.map e sl /\
(forall l, ~In l dl -> e' l = e l).
Lemma exec_par_outside:
forall m e r, ~In r (dests m) -> exec_par m e r = e r.
Lemma exec_par_lift:
forall m1 s d m2 e,
~In d (dests m1) ->
exec_par (m1 ++ (s, d) :: m2) e = exec_par ((s, d) :: m1 ++ m2) e.
Lemma exec_par_ident:
forall m1 r m2 e,
is_mill (m1 ++ (r, r) :: m2) ->
exec_par (m1 ++ (r, r) :: m2) e = exec_par (m1 ++ m2) e.
Lemma exec_seq_app:
forall m1 m2 e,
exec_seq (m1 ++ m2) e = exec_seq m2 (exec_seq m1 e).
Lemma exec_seq_rev_app:
forall m1 m2 e,
exec_seq_rev (m1 ++ m2) e = exec_seq_rev m1 (exec_seq_rev m2 e).
Lemma exec_seq_exec_seq_rev:
forall m e,
exec_seq_rev m e = exec_seq (List.rev m) e.
Lemma exec_seq_rev_exec_seq:
forall m e,
exec_seq m e = exec_seq_rev (List.rev m) e.
Lemma exec_par_update_no_read:
forall s d m e,
no_read m d ->
~In d (dests m) ->
exec_par m (update d (e s) e) =
update d (e s) (exec_par m e).
Lemma exec_par_append_eq:
forall m1 m2 m3 e2 e3,
exec_par m2 e2 = exec_par m3 e3 ->
(forall r, In r (srcs m1) -> e2 r = e3 r) ->
exec_par (m1 ++ m2) e2 = exec_par (m1 ++ m3) e3.
Lemma exec_par_combine:
forall e sl dl,
List.length sl = List.length dl ->
list_norepet dl ->
let e' := exec_par (combine sl dl) e in
List.map e' dl = List.map e sl /\
(forall l, ~In l dl -> e' l = e l).