(* 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, (exists b3 d, compose_meminj j1 j2 b1 = Some(b3,d)) <-> (exists b2 d1, j1 b1 = Some(b2,d1))) /\ (forall b2 b3 d2, j2 b2 =Some(b3,d2) -> exists b1 d, compose_meminj j1 j2 b1 = Some(b3,d)) /\ (forall b1 b2 ofs2, j1 b1 = Some(b2,ofs2) -> (b1=b2 /\ ofs2=0)) /\ (forall b2 b3 ofs3, 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))) /\ (forall b1 b2 ofs2, j1 b1 = Some(b2,ofs2) -> (b1=b2 /\ ofs2=0)) /\ (forall b2 b3 ofs3, 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))). *)
Section Eff_sim_trans.
Context {F1 V1 C1 F2 V2 C2 F3 V3 C3:Type}
(Sem1 : @EffectSem (Genv.t F1 V1) C1)
(Sem2 : @EffectSem (Genv.t F2 V2) C2)
(Sem3 : @EffectSem (Genv.t F3 V3) C3)
(g1 : Genv.t F1 V1)
(g2 : Genv.t F2 V2)
(g3 : Genv.t F3 V3)
epts12 epts23 epts13
(EPC : entrypoints_compose epts12 epts23 epts13).

Theorem eff_sim_trans: forall
(SIM12: @SM_simulation_inject _ _ _ _ _ _ Sem1 Sem2 g1 g2 epts12)
(SIM23: @SM_simulation_inject _ _ _ _ _ _ Sem2 Sem3 g2 g3 epts23),
@SM_simulation_inject _ _ _ _ _ _ Sem1 Sem3 g1 g3 epts13.