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').

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)).