(* (*It's not quite possible to obtain a transtivity proof for cc_sim from the above lemmas plus forward_simulation_trans, since the additional condititions on programs also need to be transitive*)
Goal  forall ExternIdents entrypoints12 I F1 C1 V1 F2 C2 V2
(Sem1: CoopCoreSem (Genv.t F1 V1) C1)
(Sem2: CoopCoreSem (Genv.t F2 V2) C2)
P1 P2
(SIM12: CompilerCorrectness.cc_sim I ExternIdents entrypoints12 F1 C1 V1 F2 C2 V2 Sem1 Sem2 P1 P2)
F3 V3 C3
(Sem3: CoopCoreSem (Genv.t F3 V3) C3)
entrypoints23 P3
(SIM23:CompilerCorrectness.cc_sim I ExternIdents entrypoints23 F2 C2 V2 F3 C3 V3 Sem2 Sem3 P2 P3)
entrypoints13 (EPC:entrypoints_compose entrypoints12 entrypoints23 entrypoints13),
In (P1.(prog_main), CompilerCorrectness.extern_func main_sig) ExternIdents  ->
In (P2.(prog_main), CompilerCorrectness.extern_func main_sig) ExternIdents  ->
CompilerCorrectness.cc_sim I ExternIdents entrypoints13 F1 C1 V1 F3 C3 V3 Sem1 Sem3 P1 P3.

(* Specifications: *)
Lemma ePts_compose2: forall {F1 V1 F2 V2 F3 V3}
(P1 : AST.program F1 V1) (P2 : AST.program F2 V2)
(P3 : AST.program F3 V3)
Epts12 Epts23 ExternIdents entrypoints13 jInit
(EPC : entrypoints_compose Epts12 Epts23 entrypoints13)
(ePts12_ok : CompilerCorrectness.entryPts_ok P1 P2 ExternIdents Epts12)
(ePts23_ok : CompilerCorrectness.entryPts_inject_ok P2 P3 jInit
ExternIdents Epts23),
CompilerCorrectness.entryPts_inject_ok P1 P3 jInit ExternIdents
entrypoints13.
Lemma ePts_compose3: forall {F1 V1 F2 V2 F3 V3}
(Prg1 : AST.program F1 V1) (Prg2 : AST.program F2 V2)
(Prg3 : AST.program F3 V3)
Epts12 Epts23 ExternIdents entrypoints13 j12
(EPC : entrypoints_compose Epts12 Epts23 entrypoints13)
(ePts12_ok : @CompilerCorrectness.entryPts_inject_ok F1 V1 F2 V2 Prg1
Prg2 j12 ExternIdents Epts12)
(ePts23_ok : @CompilerCorrectness.entryPts_ok F2 V2 F3 V3 Prg2
Prg3 ExternIdents Epts23),
CompilerCorrectness.entryPts_inject_ok Prg1 Prg3 j12 ExternIdents entrypoints13.
Lemma ePts_compose4: forall {F1 V1 F2 V2 F3 V3}
(Prg1 : AST.program F1 V1) (Prg2 : AST.program F2 V2)
(Prg3 : AST.program F3 V3)
Epts12 Epts23 ExternIdents entrypoints13 j12 j23
(EPC: entrypoints_compose Epts12 Epts23 entrypoints13)
(ePts12_ok: @CompilerCorrectness.entryPts_inject_ok F1 V1 F2 V2 Prg1
Prg2 j12 ExternIdents Epts12)
(ePts23_ok: @CompilerCorrectness.entryPts_inject_ok F2 V2 F3 V3 Prg2
Prg3 j23 ExternIdents Epts23),
CompilerCorrectness.entryPts_inject_ok Prg1 Prg3
(compose_meminj j12 j23) ExternIdents entrypoints13.
Lemma transform_compose: forall
{F1 F2 F3 V:Type} (P: AST.program F1 V)
(transf12: F1 -> F2) (transf23 : F2 -> F3),
transform_program transf23 (transform_program transf12 P) =
transform_program (fun f : F1 => transf23 (transf12 f)) P.