(** We axiomatize the effect of assigning a value to a register over an execution environment.  The target register is set to the given value (property [weak_update_s]), and registers disjoint from the target keep their previous values (property [weak_update_d]).  The values of other registers are undefined after the assignment. *)
Variable weak_update: reg -> val -> env -> env.
Hypothesis weak_update_s:
forall r v e, weak_update r v e r = v.
Hypothesis weak_update_d:
forall r1 v e r2, disjoint r1 r2 -> weak_update r1 v e r2 = e r2.
Fixpoint weak_exec_seq (m: moves) (e: env) {struct m}: env :=
match m with
| nil => e
| (s, d) :: m' => weak_exec_seq m' (weak_update d (e s) e)
end.
Definition disjoint_list (r: reg) (l: list reg) : Prop :=
forall r', In r' l -> disjoint r r'.
Inductive pairwise_disjoint: list reg -> Prop :=
| pairwise_disjoint_nil:
pairwise_disjoint nil
| pairwise_disjoint_cons: forall r l,
disjoint_list r l ->
pairwise_disjoint l ->
pairwise_disjoint (r :: l).
Definition disjoint_temps (r: reg) : Prop :=
forall t, is_temp t -> disjoint r t.
Section OVERLAP.
(** We consider a parallel move problem [mu] that satisfies the following conditions, which are stronger, overlap-aware variants of the [move_no_temp mu] and [is_mill mu] conditions used previously. *)
Variable mu: moves.
(** Sources and destinations are disjoint from all temporary registers. *)
Hypothesis mu_no_temporaries_src:
forall s, In s (srcs mu) -> disjoint_temps s.
Hypothesis mu_no_temporaries_dst:
forall d, In d (dests mu) -> disjoint_temps d.
(** Destinations are pairwise disjoint. *)
Hypothesis mu_dest_pairwise_disjoint:
pairwise_disjoint (dests mu).
(** Sources and destinations do not partially overlap. *)
Hypothesis mu_src_dst_no_overlap:
forall s d, In s (srcs mu) -> In d (dests mu) -> no_overlap s d.
(** Distinct temporaries do not partially overlap. *)
Hypothesis temps_no_overlap:
forall t1 t2, is_temp t1 -> is_temp t2 -> no_overlap t1 t2.
(** The following lemmas show that [mu] is a windmill and does not contain temporary registers. *)

Lemma disjoint_temps_not_temp:
forall r, disjoint_temps r -> is_not_temp r.