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. *)
(** We define the ``adherence'' of the problem [mu] as the set of registers that partially overlap with one of the registers possibly assigned by the parallel move: destinations and temporaries. Again, we define the complement of the ``adherence'' set, which is more convenient for Coq reasoning. *)
Definition no_adherence (r: reg) : Prop :=
forall x, In x (dests mu) \/ is_temp x -> no_overlap x r.
(** As a consequence of the hypotheses on [mu], none of the destination registers, source registers, and temporaries belong to the adherence. *)
(** The relation [env_match] holds between two environments [e1] and [e2] if they assign the same values to all registers not in the adherence set. *)
Definition env_match (e1 e2: env) : Prop :=
forall r, no_adherence r -> e1 r = e2 r.
(** The following lemmas relate the effect of executing moves using normal, overlap-unaware update and weak, overlap-aware update. *)
End OVERLAP.
(** These lemmas imply the following correctness theorem for the [parmove2] function, taking partial register overlap into account. *)

Theorem parmove2_correctness_with_overlap:
forall sl dl,
List.length sl = List.length dl ->
(forall r, In r sl -> disjoint_temps r) ->
(forall r, In r dl -> disjoint_temps r) ->
pairwise_disjoint dl ->
(forall s d, In s sl -> In d dl -> no_overlap s d) ->
(forall t1 t2, is_temp t1 -> is_temp t2 -> no_overlap t1 t2) ->
forall e,
let e' := weak_exec_seq (parmove2 sl dl) e in
List.map e' dl = List.map e sl /\
forall r, disjoint_list r dl -> disjoint_temps r -> e' r = e r.