Declare Module MEMAX : MemoryInterpolationAxioms.Definition entrypoints_compose
  (ep12 ep23 ep13 : list (val * val * signature)): Prop :=
  forall v1 v3 sig, In (v1,v3,sig) ep13 =
    exists v2, In (v1,v2,sig) ep12 /\ In (v2,v3,sig) ep23.Inductive sem_compose_ord_eq_eq {D12 D23:Type}
  (ord12: D12 -> D12 -> Prop) (ord23: D23 -> D23 -> Prop) (C2:Type):
  (D12 * option C2 * D23) ->  (D12 * option C2 * D23) ->  Prop :=
| sem_compose_ord1 :
  forall (d12 d12':D12) (c2:C2) (d23:D23),
    ord12 d12 d12' -> sem_compose_ord_eq_eq ord12 ord23 C2 (d12,Some c2,d23) (d12',Some c2,d23)
| sem_compose_ord2 :
  forall (d12 d12':D12) (c2 c2':C2) (d23 d23':D23),
    ord23 d23 d23' -> sem_compose_ord_eq_eq ord12 ord23 C2 (d12,Some c2,d23) (d12',Some c2',d23').Inductive sem_compose_ord_eq_eq {D12 D23:Type}
  (ord12: D12 -> D12 -> Prop) (ord23: D23 -> D23 -> Prop) (C2:Type):
  (D12 * option C2 * D23) ->  (D12 * option C2 * D23) ->  Prop :=
| sem_compose_ord1 :
  forall (d12 d12':D12) (c2:C2) (d23:D23),
    ord12 d12 d12' -> sem_compose_ord_eq_eq ord12 ord23 C2 (d12,Some c2,d23) (d12',Some c2,d23)
| sem_compose_ord2 :
  forall (d12 d12':D12) (c2 c2':C2) (d23 d23':D23),
    ord23 d23 d23' -> sem_compose_ord_eq_eq ord12 ord23 C2 (d12,Some c2,d23) (d12',Some c2',d23').Inductive sem_compose_ord_eq_eq {D12 D23:Type}
  (ord12: D12 -> D12 -> Prop) (ord23: D23 -> D23 -> Prop) (C2:Type):
  (D12 * option C2 * D23) ->  (D12 * option C2 * D23) ->  Prop :=
| sem_compose_ord1 :
  forall (d12 d12':D12) (c2:C2) (d23:D23),
    ord12 d12 d12' -> sem_compose_ord_eq_eq ord12 ord23 C2 (d12,Some c2,d23) (d12',Some c2,d23)
| sem_compose_ord2 :
  forall (d12 d12':D12) (c2 c2':C2) (d23 d23':D23),
    ord23 d23 d23' -> sem_compose_ord_eq_eq ord12 ord23 C2 (d12,Some c2,d23) (d12',Some c2',d23').

(* Specifications: *)
Lemma well_founded_sem_compose_ord_eq_eq: forall {D12 D23:Type} (ord12: D12 -> D12 -> Prop) (ord23: D23 -> D23 -> Prop) (C2:Type) (WF12: well_founded ord12) (WF23: well_founded ord23), well_founded (sem_compose_ord_eq_eq ord12 ord23 C2).
Lemma diagram_eqeq: forall (core_data12 : Type) (match_core12 : core_data12 -> C1 -> C2 -> Prop) (core_ord12 : core_data12 -> core_data12 -> Prop) (core_diagram12 : forall (st1 : C1) (m : mem) (st1' : C1) (m' : mem), corestep Sem1 g1 st1 m st1' m' -> forall (d : core_data12) (st2 : C2), match_core12 d st1 st2 -> exists st2' : C2, exists d' : core_data12, match_core12 d' st1' st2' /\ (corestep_plus Sem2 g2 st2 m st2' m' \/ corestep_star Sem2 g2 st2 m st2' m' /\ core_ord12 d' d)) (core_data23 : Type) (match_core23 : core_data23 -> C2 -> C3 -> Prop) (core_ord23 : core_data23 -> core_data23 -> Prop) (core_diagram23 : forall (st1 : C2) (m : mem) (st1' : C2) (m' : mem), corestep Sem2 g2 st1 m st1' m' -> forall (d : core_data23) (st2 : C3), match_core23 d st1 st2 -> exists st2' : C3, exists d' : core_data23, match_core23 d' st1' st2' /\ (corestep_plus Sem3 g3 st2 m st2' m' \/ corestep_star Sem3 g3 st2 m st2' m' /\ core_ord23 d' d)) (c1 : C1) (m1 : mem) (c1' : C1) (m1' : mem) (CS1 : corestep Sem1 g1 c1 m1 c1' m1') (d12 : core_data12) (d23 : core_data23) (c3 : C3) (c2 : C2) (MC12 : match_core12 d12 c1 c2) (MC23 : match_core23 d23 c2 c3), exists st2' : C3, exists d' : core_data12 * option C2 * core_data23, (let (y, d2) := d' in let (d1, X) := y in exists c0 : C2, X = Some c0 /\ match_core12 d1 c1' c0 /\ match_core23 d2 c0 st2') /\ (corestep_plus Sem3 g3 c3 m1 st2' m1' \/ corestep_star Sem3 g3 c3 m1 st2' m1' /\ clos_trans (core_data12 * option C2 * core_data23) (sem_compose_ord_eq_eq core_ord12 core_ord23 C2) d' (d12, Some c2, d23)).
Lemma eqeq: forall (SimEq12 : Forward_simulation_equals Sem1 Sem2 g1 g2 epts12) (SimEq23 : Forward_simulation_equals Sem2 Sem3 g2 g3 epts23), Forward_simulation_equals Sem1 Sem3 g1 g3 epts13.
Lemma diagram_eqext: forall (core_data12 : Type) (match_core12 : core_data12 -> C1 -> C2 -> Prop) (core_ord12 : core_data12 -> core_data12 -> Prop) (core_diagram12 : forall (st1 : C1) (m : mem) (st1' : C1) (m' : mem), corestep Sem1 g1 st1 m st1' m' -> forall (d : core_data12) (st2 : C2), match_core12 d st1 st2 -> exists st2' : C2, exists d' : core_data12, match_core12 d' st1' st2' /\ (corestep_plus Sem2 g2 st2 m st2' m' \/ corestep_star Sem2 g2 st2 m st2' m' /\ core_ord12 d' d)) (core_data23 : Type) (match_core23 : core_data23 -> C2 -> mem -> C3 -> mem -> Prop) (core_ord23 : core_data23 -> core_data23 -> Prop) (core_diagram23 : forall (st1 : C2) (m1 : mem) (st1' : C2) (m1' : mem), corestep Sem2 g2 st1 m1 st1' m1' -> forall (cd : core_data23) (st2 : C3) (m2 : mem), match_core23 cd st1 m1 st2 m2 -> exists st2' : C3, exists m2' : mem, exists cd' : core_data23, match_core23 cd' st1' m1' st2' m2' /\ (corestep_plus Sem3 g3 st2 m2 st2' m2' \/ corestep_star Sem3 g3 st2 m2 st2' m2' /\ core_ord23 cd' cd)) (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem) (CS1 : corestep Sem1 g1 st1 m1 st1' m1') (d12 : core_data12) (d23 : core_data23) (st3 : C3) (m3 : mem) (st2 : C2) (MC12: match_core12 d12 st1 st2) (MC23: match_core23 d23 st2 m1 st3 m3), exists st2' : C3, exists m2' : mem, exists cd' : core_data12 * option C2 * core_data23, (let (y, d2) := cd' in let (d1, X) := y in exists c2 : C2, X = Some c2 /\ match_core12 d1 st1' c2 /\ match_core23 d2 c2 m1' st2' m2') /\ (corestep_plus Sem3 g3 st3 m3 st2' m2' \/ corestep_star Sem3 g3 st3 m3 st2' m2' /\ clos_trans (core_data12 * option C2 * core_data23) (sem_compose_ord_eq_eq core_ord12 core_ord23 C2) cd' (d12, Some st2, d23)).
Lemma eqext: forall (SimEq12 : Forward_simulation_equals Sem1 Sem2 g1 g2 epts12) (SimExt23 : Forward_simulation_extends Sem2 Sem3 g2 g3 epts23), Forward_simulation_extends Sem1 Sem3 g1 g3 epts13.
Lemma X: forall {A B} (f g: A ->B) (H: (fun b => f b) = (fun b => g b)) b, f b = g b.
Lemma diagram_eqinj: forall (core_data12 : Type) (match_core12 : core_data12 -> C1 -> C2 -> Prop) (core_ord12 : core_data12 -> core_data12 -> Prop) (core_diagram12 : forall (st1 : C1) (m : mem) (st1' : C1) (m' : mem), corestep Sem1 g1 st1 m st1' m' -> forall (d : core_data12) (st2 : C2), match_core12 d st1 st2 -> exists st2' : C2, exists d' : core_data12, match_core12 d' st1' st2' /\ (corestep_plus Sem2 g2 st2 m st2' m' \/ corestep_star Sem2 g2 st2 m st2' m' /\ core_ord12 d' d)) (core_data23 : Type) (match_core23 : core_data23 -> meminj -> C2 -> mem -> C3 -> mem -> Prop) (core_ord23 : core_data23 -> core_data23 -> Prop) (core_diagram23 : forall (st1 : C2) (m1 : mem) (st1' : C2) (m1' : mem), corestep Sem2 g2 st1 m1 st1' m1' -> forall (cd : core_data23) (st2 : C3) (j : meminj) (m2 : mem), match_core23 cd j st1 m1 st2 m2 -> exists st2' : C3, exists m2' : mem, exists cd' : core_data23, exists j' : meminj, inject_incr j j' /\ inject_separated j j' m1 m2 /\ match_core23 cd' j' st1' m1' st2' m2' /\ (corestep_plus Sem3 g3 st2 m2 st2' m2' \/ corestep_star Sem3 g3 st2 m2 st2' m2' /\ core_ord23 cd' cd)) (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem) (CS1 : corestep Sem1 g1 st1 m1 st1' m1') (d12 : core_data12) (d23 : core_data23) (st3 : C3) (j : meminj) (m3 : mem) (st2 : C2) (MC12: match_core12 d12 st1 st2) (MC23: match_core23 d23 j st2 m1 st3 m3), exists st2' : C3, exists m2' : mem, exists cd' : core_data12 * option C2 * core_data23, exists j' : meminj, inject_incr j j' /\ inject_separated j j' m1 m3 /\ (let (y, d2) := cd' in let (d1, X) := y in exists c2 : C2, X = Some c2 /\ match_core12 d1 st1' c2 /\ match_core23 d2 j' c2 m1' st2' m2') /\ (corestep_plus Sem3 g3 st3 m3 st2' m2' \/ corestep_star Sem3 g3 st3 m3 st2' m2' /\ clos_trans (core_data12 * option C2 * core_data23) (sem_compose_ord_eq_eq core_ord12 core_ord23 C2) cd' (d12, Some st2, d23)).
Lemma eqinj: forall (SimEq12 : Forward_simulation_equals Sem1 Sem2 g1 g2 epts12) (SimInj23 : Forward_simulation_inject Sem2 Sem3 g2 g3 epts23), Forward_simulation_inject Sem1 Sem3 g1 g3 epts13.
Lemma coop_sim_trans_CaseEq: forall (SimEq12 : Forward_simulation_equals Sem1 Sem2 g1 g2 epts12) (SIM23 : coop_sim Sem2 Sem3 g2 g3 epts23), coop_sim Sem1 Sem3 g1 g3 epts13.
Lemma diagram_exteq: forall (core_data12 : Type) (match_core12 : core_data12 -> C1 -> mem -> C2 -> mem -> Prop) (core_ord12 : core_data12 -> core_data12 -> Prop) (core_diagram12 : forall (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem), corestep Sem1 g1 st1 m1 st1' m1' -> forall (cd : core_data12) (st2 : C2) (m2 : mem), match_core12 cd st1 m1 st2 m2 -> exists st2' : C2, exists m2' : mem, exists cd' : core_data12, match_core12 cd' st1' m1' st2' m2' /\ (corestep_plus Sem2 g2 st2 m2 st2' m2' \/ corestep_star Sem2 g2 st2 m2 st2' m2' /\ core_ord12 cd' cd)) (core_data23 : Type) (match_core23 : core_data23 -> C2 -> C3 -> Prop) (core_ord23 : core_data23 -> core_data23 -> Prop) (core_diagram23 : forall (st1 : C2) (m : mem) (st1' : C2) (m' : mem), corestep Sem2 g2 st1 m st1' m' -> forall (d : core_data23) (st2 : C3), match_core23 d st1 st2 -> exists st2' : C3, exists d' : core_data23, match_core23 d' st1' st2' /\ (corestep_plus Sem3 g3 st2 m st2' m' \/ corestep_star Sem3 g3 st2 m st2' m' /\ core_ord23 d' d)) (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem) (CS1 : corestep Sem1 g1 st1 m1 st1' m1') (d12 : core_data12) (d23 : core_data23) (st3 : C3) (m3 : mem) (st2 : C2) (MC12 : match_core12 d12 st1 m1 st2 m3) (MC23: match_core23 d23 st2 st3), exists st3' : C3, exists m3' : mem, exists cd' : core_data12 * option C2 * core_data23, (let (y, d2) := cd' in let (d1, X) := y in exists c2 : C2, X = Some c2 /\ match_core12 d1 st1' m1' c2 m3' /\ match_core23 d2 c2 st3') /\ (corestep_plus Sem3 g3 st3 m3 st3' m3' \/ corestep_star Sem3 g3 st3 m3 st3' m3' /\ clos_trans (core_data12 * option C2 * core_data23) (sem_compose_ord_eq_eq core_ord12 core_ord23 C2) cd' (d12, Some st2, d23)).
Lemma exteq: forall (SimExt12 : Forward_simulation_extends Sem1 Sem2 g1 g2 epts12) (SimEq23 : Forward_simulation_equals Sem2 Sem3 g2 g3 epts23), Forward_simulation_extends Sem1 Sem3 g1 g3 epts13.
Lemma diagram_extext: forall (core_data12 : Type) (match_core12 : core_data12 -> C1 -> mem -> C2 -> mem -> Prop) (core_ord12 : core_data12 -> core_data12 -> Prop) (core_diagram12 : forall (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem), corestep Sem1 g1 st1 m1 st1' m1' -> forall (cd : core_data12) (st2 : C2) (m2 : mem), match_core12 cd st1 m1 st2 m2 -> exists st2' : C2, exists m2' : mem, exists cd' : core_data12, match_core12 cd' st1' m1' st2' m2' /\ (corestep_plus Sem2 g2 st2 m2 st2' m2' \/ corestep_star Sem2 g2 st2 m2 st2' m2' /\ core_ord12 cd' cd)) (core_data23 : Type) (match_core23 : core_data23 -> C2 -> mem -> C3 -> mem -> Prop) (core_ord23 : core_data23 -> core_data23 -> Prop) (core_diagram23 : forall (st1 : C2) (m1 : mem) (st1' : C2) (m1' : mem), corestep Sem2 g2 st1 m1 st1' m1' -> forall (cd : core_data23) (st2 : C3) (m2 : mem), match_core23 cd st1 m1 st2 m2 -> exists st2' : C3, exists m2' : mem, exists cd' : core_data23, match_core23 cd' st1' m1' st2' m2' /\ (corestep_plus Sem3 g3 st2 m2 st2' m2' \/ corestep_star Sem3 g3 st2 m2 st2' m2' /\ core_ord23 cd' cd)) (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem) (CS1 : corestep Sem1 g1 st1 m1 st1' m1') (d12 : core_data12) (d23 : core_data23) (st3 : C3) (m3 : mem) (st2 : C2) (m2 : mem) (MC12 : match_core12 d12 st1 m1 st2 m2) (MC23 : match_core23 d23 st2 m2 st3 m3), exists st3' : C3, exists m3' : mem, exists cd' : core_data12 * option C2 * core_data23, (let (y, d2) := cd' in let (d1, X) := y in exists c2 : C2, exists m2 : mem, X = Some c2 /\ match_core12 d1 st1' m1' c2 m2 /\ match_core23 d2 c2 m2 st3' m3') /\ (corestep_plus Sem3 g3 st3 m3 st3' m3' \/ corestep_star Sem3 g3 st3 m3 st3' m3' /\ clos_trans (core_data12 * option C2 * core_data23) (sem_compose_ord_eq_eq core_ord12 core_ord23 C2) cd' (d12, Some st2, d23)).
Lemma extext: forall (SimExt12 : Forward_simulation_extends Sem1 Sem2 g1 g2 epts12) (SimExt23 : Forward_simulation_extends Sem2 Sem3 g2 g3 epts23), Forward_simulation_extends Sem1 Sem3 g1 g3 epts13.
Lemma diagram_extinj: forall (core_data12 : Type) (match_core12 : core_data12 -> C1 -> mem -> C2 -> mem -> Prop) (core_ord12 : core_data12 -> core_data12 -> Prop) (core_diagram12 : forall (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem), corestep Sem1 g1 st1 m1 st1' m1' -> forall (cd : core_data12) (st2 : C2) (m2 : mem), match_core12 cd st1 m1 st2 m2 -> exists st2' : C2, exists m2' : mem, exists cd' : core_data12, match_core12 cd' st1' m1' st2' m2' /\ (corestep_plus Sem2 g2 st2 m2 st2' m2' \/ corestep_star Sem2 g2 st2 m2 st2' m2' /\ core_ord12 cd' cd)) (core_data23 : Type) (match_core23 : core_data23 -> meminj -> C2 -> mem -> C3 -> mem -> Prop) (core_ord23 : core_data23 -> core_data23 -> Prop) (core_diagram23 : forall (st1 : C2) (m1 : mem) (st1' : C2) (m1' : mem), corestep Sem2 g2 st1 m1 st1' m1' -> forall (cd : core_data23) (st2 : C3) (j : meminj) (m2 : mem), match_core23 cd j st1 m1 st2 m2 -> exists st2' : C3, exists m2' : mem, exists cd' : core_data23, exists j' : meminj, inject_incr j j' /\ inject_separated j j' m1 m2 /\ match_core23 cd' j' st1' m1' st2' m2' /\ (corestep_plus Sem3 g3 st2 m2 st2' m2' \/ corestep_star Sem3 g3 st2 m2 st2' m2' /\ core_ord23 cd' cd)) (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem) (CS1 : corestep Sem1 g1 st1 m1 st1' m1') (d12 : core_data12) (d23 : core_data23) (st3 : C3) (j : meminj) (m3 : mem) (st2 : C2) (m2 : mem) (MC12 : match_core12 d12 st1 m1 st2 m2) (MC23 : match_core23 d23 j st2 m2 st3 m3) (match_validblocks12: forall cd st1 m1 st2 m2, match_core12 cd st1 m1 st2 m2 -> (forall b, Mem.valid_block m1 b -> Mem.valid_block m2 b)), exists st3' : C3, exists m3' : mem, exists cd' : core_data12 * option C2 * core_data23, exists j' : meminj, inject_incr j j' /\ inject_separated j j' m1 m3 /\ (let (y, d2) := cd' in let (d1, X) := y in exists c2 : C2, exists m2' : mem, X = Some c2 /\ match_core12 d1 st1' m1' c2 m2' /\ match_core23 d2 j' c2 m2' st3' m3') /\ (corestep_plus Sem3 g3 st3 m3 st3' m3' \/ corestep_star Sem3 g3 st3 m3 st3' m3' /\ clos_trans (core_data12 * option C2 * core_data23) (sem_compose_ord_eq_eq core_ord12 core_ord23 C2) cd' (d12, Some st2, d23)).
Lemma extinj: forall (SimExt12 : Forward_simulation_extends Sem1 Sem2 g1 g2 epts12) (SimInj23 : Forward_simulation_inject Sem2 Sem3 g2 g3 epts23), Forward_simulation_inject Sem1 Sem3 g1 g3 epts13.
Lemma coop_sim_trans_CaseExt: forall (SimExt12 : Forward_simulation_extends Sem1 Sem2 g1 g2 epts12) (SIM23 : coop_sim Sem2 Sem3 g2 g3 epts23), coop_sim Sem1 Sem3 g1 g3 epts13.
Lemma diagram_injeq: forall (core_data12 : Type) (match_core12 : core_data12 -> meminj -> C1 -> mem -> C2 -> mem -> Prop) (core_ord12 : core_data12 -> core_data12 -> Prop) (core_diagram12 : forall (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem), corestep Sem1 g1 st1 m1 st1' m1' -> forall (cd : core_data12) (st2 : C2) (j : meminj) (m2 : mem), match_core12 cd j st1 m1 st2 m2 -> exists st2' : C2, exists m2' : mem, exists cd' : core_data12, exists j' : meminj, inject_incr j j' /\ inject_separated j j' m1 m2 /\ match_core12 cd' j' st1' m1' st2' m2' /\ (corestep_plus Sem2 g2 st2 m2 st2' m2' \/ corestep_star Sem2 g2 st2 m2 st2' m2' /\ core_ord12 cd' cd)) (core_data23 : Type) (match_core23 : core_data23 -> C2 -> C3 -> Prop) (core_ord23 : core_data23 -> core_data23 -> Prop) (core_diagram23 : forall (st1 : C2) (m : mem) (st1' : C2) (m' : mem), corestep Sem2 g2 st1 m st1' m' -> forall (d : core_data23) (st2 : C3), match_core23 d st1 st2 -> exists st2' : C3, exists d' : core_data23, match_core23 d' st1' st2' /\ (corestep_plus Sem3 g3 st2 m st2' m' \/ corestep_star Sem3 g3 st2 m st2' m' /\ core_ord23 d' d)) (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem) (CS1 : corestep Sem1 g1 st1 m1 st1' m1') (d12 : core_data12) (d23 : core_data23) (st3 : C3) (j : meminj) (m2 : mem) (st2 : C2) (MC12 : match_core12 d12 j st1 m1 st2 m2) (MC23 : match_core23 d23 st2 st3), exists st3' : C3, exists m2' : mem, exists cd' : core_data12 * option C2 * core_data23, exists j' : meminj, inject_incr j j' /\ inject_separated j j' m1 m2 /\ (let (y, d2) := cd' in let (d1, X) := y in exists c2 : C2, X = Some c2 /\ match_core12 d1 j' st1' m1' c2 m2' /\ match_core23 d2 c2 st3') /\ (corestep_plus Sem3 g3 st3 m2 st3' m2' \/ corestep_star Sem3 g3 st3 m2 st3' m2' /\ clos_trans (core_data12 * option C2 * core_data23) (sem_compose_ord_eq_eq core_ord12 core_ord23 C2) cd' (d12, Some st2, d23)).
Lemma injeq: forall (SimInj12 : Forward_simulation_inject Sem1 Sem2 g1 g2 epts12) (SimEq23 : Forward_simulation_equals Sem2 Sem3 g2 g3 epts23), Forward_simulation_inject Sem1 Sem3 g1 g3 epts13.
Lemma diagram_injext: forall (core_data12 : Type) (match_core12 : core_data12 -> meminj -> C1 -> mem -> C2 -> mem -> Prop) (core_ord12 : core_data12 -> core_data12 -> Prop) (core_diagram12 : forall (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem), corestep Sem1 g1 st1 m1 st1' m1' -> forall (cd : core_data12) (st2 : C2) (j : meminj) (m2 : mem), match_core12 cd j st1 m1 st2 m2 -> exists st2' : C2, exists m2' : mem, exists cd' : core_data12, exists j' : meminj, inject_incr j j' /\ inject_separated j j' m1 m2 /\ match_core12 cd' j' st1' m1' st2' m2' /\ (corestep_plus Sem2 g2 st2 m2 st2' m2' \/ corestep_star Sem2 g2 st2 m2 st2' m2' /\ core_ord12 cd' cd)) (core_data23 : Type) (match_core23 : core_data23 -> C2 -> mem -> C3 -> mem -> Prop) (core_ord23 : core_data23 -> core_data23 -> Prop) (core_diagram23 : forall (st1 : C2) (m1 : mem) (st1' : C2) (m1' : mem), corestep Sem2 g2 st1 m1 st1' m1' -> forall (cd : core_data23) (st2 : C3) (m2 : mem), match_core23 cd st1 m1 st2 m2 -> exists st2' : C3, exists m2' : mem, exists cd' : core_data23, match_core23 cd' st1' m1' st2' m2' /\ (corestep_plus Sem3 g3 st2 m2 st2' m2' \/ corestep_star Sem3 g3 st2 m2 st2' m2' /\ core_ord23 cd' cd)) (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem) (CS1 : corestep Sem1 g1 st1 m1 st1' m1') (d12 : core_data12) (d23 : core_data23) (st3 : C3) (j : meminj) (m3 : mem) (st2 : C2) (m2 : mem) (MC12: match_core12 d12 j st1 m1 st2 m2) (MC23: match_core23 d23 st2 m2 st3 m3) (MatchHyp12: forall d12 j12 c1 m1 c2 m2, match_core12 d12 j12 c1 m1 c2 m2 -> forall b1 b2 ofs, j12 b1 = Some (b2,ofs) -> Mem.valid_block m1 b1 /\ Mem.valid_block m2 b2) (MatchHyp23: forall d23 c2 m2 c3 m3, match_core23 d23 c2 m2 c3 m3 -> forall b, Mem.valid_block m2 b <-> Mem.valid_block m3 b), exists st2' : C3, exists m2' : mem, exists cd' : core_data12 * option C2 * core_data23, exists j' : meminj, inject_incr j j' /\ inject_separated j j' m1 m3 /\ (let (y, d2) := cd' in let (d1, X) := y in exists c2 : C2, exists m0 : mem, X = Some c2 /\ match_core12 d1 j' st1' m1' c2 m0 /\ match_core23 d2 c2 m0 st2' m2') /\ (corestep_plus Sem3 g3 st3 m3 st2' m2' \/ corestep_star Sem3 g3 st3 m3 st2' m2' /\ clos_trans (core_data12 * option C2 * core_data23) (sem_compose_ord_eq_eq core_ord12 core_ord23 C2) cd' (d12, Some st2, d23)).
Lemma injext: forall (SimInj12 : Forward_simulation_inject Sem1 Sem2 g1 g2 epts12) (SimExt23 : Forward_simulation_extends Sem2 Sem3 g2 g3 epts23), Forward_simulation_inject Sem1 Sem3 g1 g3 epts13.
Lemma empty_inj: Mem.inject (Mem.flat_inj 1%positive) Mem.empty Mem.empty.
Lemma empty_fwd: forall m, mem_forward Mem.empty m.
Lemma inject_split: forall j m1 m3 (Inj:Mem.inject j m1 m3), exists m2 j1 j2, j = compose_meminj j1 j2 /\ Mem.inject j1 m1 m2 /\ Mem.inject j2 m2 m3.
Lemma forall_val_inject_split: forall j1 j2 vals1 vals3 (V: Forall2 (val_inject (compose_meminj j1 j2)) vals1 vals3), exists vals2, Forall2 (val_inject j1) vals1 vals2 /\ Forall2 (val_inject j2) vals2 vals3.
Lemma initial_inject_split: forall j m1 m3 (Inj:Mem.inject j m1 m3), exists m2 j1 j2, j = compose_meminj j1 j2 /\ Mem.inject j1 m1 m2 /\ Mem.inject j2 m2 m3 /\ (forall b1 b2 ofs2, j1 b1 = Some(b2,ofs2) -> (b1=b2 /\ ofs2=0)) /\ (forall (b2 b3 : block) (ofs3 : Z), j2 b2 = Some (b3, ofs3) -> Mem.flat_inj 1%positive b2 = Some (b3, ofs3) \/ b2 = Mem.nextblock Mem.empty /\ compose_meminj j1 j2 (Mem.nextblock Mem.empty) = Some (b3, ofs3) \/ (exists m : positive, b2 = (Mem.nextblock Mem.empty + m)%positive /\ compose_meminj j1 j2 (Mem.nextblock Mem.empty + m)%positive = Some (b3, ofs3))).
Lemma diagram_injinj: forall (core_data12 : Type) (match_core12 : core_data12 -> meminj -> C1 -> mem -> C2 -> mem -> Prop) (core_ord12 : core_data12 -> core_data12 -> Prop) (core_diagram12 : forall (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem), corestep Sem1 g1 st1 m1 st1' m1' -> forall (cd : core_data12) (st2 : C2) (j : meminj) (m2 : mem), match_core12 cd j st1 m1 st2 m2 -> exists st2' : C2, exists m2' : mem, exists cd' : core_data12, exists j' : meminj, inject_incr j j' /\ inject_separated j j' m1 m2 /\ match_core12 cd' j' st1' m1' st2' m2' /\ (corestep_plus Sem2 g2 st2 m2 st2' m2' \/ corestep_star Sem2 g2 st2 m2 st2' m2' /\ core_ord12 cd' cd)) (core_data23 : Type) (match_core23 : core_data23 -> meminj -> C2 -> mem -> C3 -> mem -> Prop) (core_ord23 : core_data23 -> core_data23 -> Prop) (core_diagram23 : forall (st1 : C2) (m1 : mem) (st1' : C2) (m1' : mem), corestep Sem2 g2 st1 m1 st1' m1' -> forall (cd : core_data23) (st2 : C3) (j : meminj) (m2 : mem), match_core23 cd j st1 m1 st2 m2 -> exists st2' : C3, exists m2' : mem, exists cd' : core_data23, exists j' : meminj, inject_incr j j' /\ inject_separated j j' m1 m2 /\ match_core23 cd' j' st1' m1' st2' m2' /\ (corestep_plus Sem3 g3 st2 m2 st2' m2' \/ corestep_star Sem3 g3 st2 m2 st2' m2' /\ core_ord23 cd' cd)) (MatchHyp12: forall d12 j12 c1 m1 c2 m2, match_core12 d12 j12 c1 m1 c2 m2 -> forall b1 b2 ofs, j12 b1 = Some (b2,ofs) -> Mem.valid_block m1 b1 /\ Mem.valid_block m2 b2) (MatchHyp23: forall d23 j23 c2 m2 c3 m3, match_core23 d23 j23 c2 m2 c3 m3 -> forall b1 b2 ofs, j23 b1 = Some (b2,ofs) -> Mem.valid_block m2 b1 /\ Mem.valid_block m3 b2) (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem) (CS1 : corestep Sem1 g1 st1 m1 st1' m1') (d12 : core_data12) (d23 : core_data23) (st3 : C3) (m3 : mem) (st2 : C2) (m2 : mem) (j12 : meminj) (j23 : meminj) (MC12 : match_core12 d12 j12 st1 m1 st2 m2) (MC23 : match_core23 d23 j23 st2 m2 st3 m3), exists st3' : C3, exists m3' : mem, exists cd' : core_data12 * option C2 * core_data23, exists j' : meminj, inject_incr (compose_meminj j12 j23) j' /\ inject_separated (compose_meminj j12 j23) j' m1 m3 /\ (let (y, d2) := cd' in let (d1, X) := y in exists st2' : C2, exists m2' : mem, exists j12' : meminj, exists j23' : meminj, X = Some st2' /\ j' = compose_meminj j12' j23' /\ match_core12 d1 j12' st1' m1' st2' m2' /\ match_core23 d2 j23' st2' m2' st3' m3') /\ (corestep_plus Sem3 g3 st3 m3 st3' m3' \/ corestep_star Sem3 g3 st3 m3 st3' m3' /\ clos_trans (core_data12 * option C2 * core_data23) (sem_compose_ord_eq_eq core_ord12 core_ord23 C2) cd' (d12, Some st2, d23)).
Lemma diagram_injinj_injsep: forall (core_data12 : Type) (match_core12 : core_data12 -> meminj -> C1 -> mem -> C2 -> mem -> Prop) (core_ord12 : core_data12 -> core_data12 -> Prop) (core_diagram12 : forall (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem), corestep Sem1 g1 st1 m1 st1' m1' -> forall (cd : core_data12) (st2 : C2) (j : meminj) (m2 : mem), match_core12 cd j st1 m1 st2 m2 -> exists st2' : C2, exists m2' : mem, exists cd' : core_data12, exists j' : meminj, inject_incr j j' /\ inject_separated j j' m1 m2 /\ match_core12 cd' j' st1' m1' st2' m2' /\ (corestep_plus Sem2 g2 st2 m2 st2' m2' \/ corestep_star Sem2 g2 st2 m2 st2' m2' /\ core_ord12 cd' cd)) (core_data23 : Type) (match_core23 : core_data23 -> meminj -> C2 -> mem -> C3 -> mem -> Prop) (core_ord23 : core_data23 -> core_data23 -> Prop) (core_diagram23 : forall (st1 : C2) (m1 : mem) (st1' : C2) (m1' : mem), corestep Sem2 g2 st1 m1 st1' m1' -> forall (cd : core_data23) (st2 : C3) (j : meminj) (m2 : mem), match_core23 cd j st1 m1 st2 m2 -> exists st2' : C3, exists m2' : mem, exists cd' : core_data23, exists j' : meminj, inject_incr j j' /\ inject_separated j j' m1 m2 /\ match_core23 cd' j' st1' m1' st2' m2' /\ (corestep_plus Sem3 g3 st2 m2 st2' m2' \/ corestep_star Sem3 g3 st2 m2 st2' m2' /\ core_ord23 cd' cd)) (MatchHyp12: forall d12 j12 c1 m1 c2 m2, match_core12 d12 j12 c1 m1 c2 m2 -> forall b1 b2 ofs, j12 b1 = Some (b2,ofs) -> Mem.valid_block m1 b1 /\ Mem.valid_block m2 b2) (MatchHyp23: forall d23 j23 c2 m2 c3 m3, match_core23 d23 j23 c2 m2 c3 m3 -> forall b1 b2 ofs, j23 b1 = Some (b2,ofs) -> Mem.valid_block m2 b1 /\ Mem.valid_block m3 b2) (st1 : C1) (m1 : mem) (st1' : C1) (m1' : mem) (CS1 : corestep Sem1 g1 st1 m1 st1' m1') (d12 : core_data12) (d23 : core_data23) (st3 : C3) (m3 : mem) (st2 : C2) (m2 : mem) (j12 : meminj) (j23 : meminj) (MC12 : match_core12 d12 j12 st1 m1 st2 m2) (MC23 : match_core23 d23 j23 st2 m2 st3 m3), exists st3' : C3, exists m3' : mem, exists cd' : core_data12 * option C2 * core_data23, exists j' : meminj, inject_incr (compose_meminj j12 j23) j' /\ inject_separated (compose_meminj j12 j23) j' m1 m3 /\ (let (y, d2) := cd' in let (d1, X) := y in exists st2' : C2, exists m2' : mem, exists j12' : meminj, exists j23' : meminj, X = Some st2' /\ j' = compose_meminj j12' j23' /\ match_core12 d1 j12' st1' m1' st2' m2' /\ match_core23 d2 j23' st2' m2' st3' m3' /\ inject_incr j12 j12' /\ inject_incr j23 j23' /\ inject_separated j12 j12' m1 m2 /\ inject_separated j23 j23' m2 m3) /\ (corestep_plus Sem3 g3 st3 m3 st3' m3' \/ corestep_star Sem3 g3 st3 m3 st3' m3' /\ clos_trans (core_data12 * option C2 * core_data23) (sem_compose_ord_eq_eq core_ord12 core_ord23 C2) cd' (d12, Some st2, d23)).
Lemma injinj: forall (SimInj12 : Forward_simulation_inject Sem1 Sem2 g1 g2 epts12) (SimInj23 : Forward_simulation_inject Sem2 Sem3 g2 g3 epts23), Forward_simulation_inject Sem1 Sem3 g1 g3 epts13.
Lemma coop_sim_trans_CaseInj: forall (SimInj12 : Forward_simulation_inject Sem1 Sem2 g1 g2 epts12) (SIM23 : coop_sim Sem2 Sem3 g2 g3 epts23), coop_sim Sem1 Sem3 g1 g3 epts13.
Theorem coop_sim_trans: forall (SIM12: coop_sim Sem1 Sem2 g1 g2 epts12) (SIM23: coop_sim Sem2 Sem3 g2 g3 epts23), coop_sim Sem1 Sem3 g1 g3 epts13.