(* (*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.

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.