Definition main_sig : signature := mksignature nil (Some AST.Tint).

(* Specifications: *)
Lemma cc_sim_coop_sim: forall {F1 C1 V1 F2 C2 V2:Type} (Sem1 : CoopCoreSem (Genv.t F1 V1) C1) (Sem2 : CoopCoreSem(Genv.t F2 V2) C2) (P1 : AST.program F1 V1) (P2 : AST.program F2 V2) I epts ExternIdents (CCSim: CompilerCorrectness.cc_sim I ExternIdents epts F1 C1 V1 F2 C2 V2 Sem1 Sem2 P1 P2), Forward_simulation.coop_sim Sem1 Sem2 (Genv.globalenv P1) (Genv.globalenv P2) epts.
Lemma coop_sim_cc_sim: forall {F1 C1 V1 F2 C2 V2:Type} (Sem1 : CoopCoreSem (Genv.t F1 V1) C1) (Sem2 : CoopCoreSem(Genv.t F2 V2) C2) (P1 : AST.program F1 V1) (P2 : AST.program F2 V2) (I: forall F C V (Sem : CoopCoreSem (Genv.t F V) C) (P : AST.program F V), Prop) epts ExternIdents (InitMem: forall m1 : mem, Genv.init_mem P1 = Some m1 -> Genv.init_mem P2 = Some m1) (Epts: CompilerCorrectness.entryPts_ok P1 P2 ExternIdents epts) (Main: prog_main P1 = prog_main P2) (GENV: CompilerCorrectness.GenvHyp P1 P2) (HP1: I F1 C1 V1 Sem1 P1) (HP2: I F2 C2 V2 Sem2 P2) (Externs: CompilerCorrectness.externvars_ok P1 ExternIdents) m (IM: Genv.init_mem P1 = Some m), Forward_simulation.coop_sim Sem1 Sem2 (Genv.globalenv P1) (Genv.globalenv P2) epts -> CompilerCorrectness.cc_sim I ExternIdents epts F1 C1 V1 F2 C2 V2 Sem1 Sem2 P1 P2.
Lemma ePts_compose1: 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 (EPC : entrypoints_compose Epts12 Epts23 entrypoints13) (ePts12_ok : @CompilerCorrectness.entryPts_ok F1 V1 F2 V2 Prg1 Prg2 ExternIdents Epts12) (ePts23_ok : @CompilerCorrectness.entryPts_ok F2 V2 F3 V3 Prg2 Prg3 ExternIdents Epts23), CompilerCorrectness.entryPts_ok Prg1 Prg3 ExternIdents entrypoints13.
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.
Lemma ccT_trans_CaseEq: forall {F1 C1 V F2 C2 F3 C3} (Sem1 : CoopCoreSem (Genv.t F1 V) C1) (Sem2 : CoopCoreSem (Genv.t F2 V) C2) (Sem3 : CoopCoreSem (Genv.t F3 V) C3) ExternIdents epts12 epts23 I (P1 : AST.program F1 V) (P2 : AST.program F2 V) (P3 : AST.program F3 V) transf12 (HP12: P2=transform_program transf12 P1) transf23 (ePts12_ok : CompilerCorrectness.entryPts_ok P1 P2 ExternIdents epts12) (SimEq12 : Forward_simulation_eq.Forward_simulation_equals Sem1 Sem2 (Genv.globalenv P1) (Genv.globalenv P2) epts12) (SIM23 : CompilerCorrectness.cc_simT I ExternIdents epts23 F2 C2 V F3 C3 Sem2 Sem3 P2 P3 transf23) (i1: I F1 C1 V Sem1 P1), forall entrypoints13 : list (val * val * signature), entrypoints_compose epts12 epts23 entrypoints13 -> CompilerCorrectness.cc_simT I ExternIdents entrypoints13 F1 C1 V F3 C3 Sem1 Sem3 P1 P3 (fun f => transf23 (transf12 f)).
Lemma ccT_trans_CaseExtends: forall {F1 C1 V F2 C2 F3 C3} (Sem1 : CoopCoreSem (Genv.t F1 V) C1) (Sem2 : CoopCoreSem (Genv.t F2 V) C2) (Sem3 : CoopCoreSem (Genv.t F3 V) C3) ExternIdents epts12 epts23 I (P1 : AST.program F1 V) (P2 : AST.program F2 V) (P3 : AST.program F3 V) transf12 (HP12: P2=transform_program transf12 P1) transf23 (ePts12_ok : CompilerCorrectness.entryPts_ok P1 P2 ExternIdents epts12) (SimExt12 : Forward_simulation_ext.Forward_simulation_extends Sem1 Sem2 (Genv.globalenv P1) (Genv.globalenv P2) epts12) (SIM23 : CompilerCorrectness.cc_simT I ExternIdents epts23 F2 C2 V F3 C3 Sem2 Sem3 P2 P3 transf23) (i1: I F1 C1 V Sem1 P1), forall entrypoints13 : list (val * val * signature), entrypoints_compose epts12 epts23 entrypoints13 -> CompilerCorrectness.cc_simT I ExternIdents entrypoints13 F1 C1 V F3 C3 Sem1 Sem3 P1 P3 (fun f => transf23 (transf12 f)).
Lemma ccT_trans_CaseInject: forall {F1 C1 V F2 C2 F3 C3} (Sem1 : CoopCoreSem (Genv.t F1 V) C1) (Sem2 : CoopCoreSem (Genv.t F2 V) C2) (Sem3 : CoopCoreSem (Genv.t F3 V) C3) ExternIdents epts12 epts23 I (P1 : AST.program F1 V) (P2 : AST.program F2 V) (P3 : AST.program F3 V) transf12 (HP12: P2=transform_program transf12 P1) transf23 (ePts12_ok: forall m, Genv.init_mem P1 = Some m -> CompilerCorrectness.entryPts_inject_ok P1 P2 (Mem.flat_inj (Mem.nextblock m)) ExternIdents epts12) (VarsOK1: CompilerCorrectness.externvars_ok P1 ExternIdents) (SimInj12: Forward_simulation_inj.Forward_simulation_inject Sem1 Sem2 (Genv.globalenv P1) (Genv.globalenv P2) epts12) (SIM23 : CompilerCorrectness.cc_simT I ExternIdents epts23 F2 C2 V F3 C3 Sem2 Sem3 P2 P3 transf23) (i1: I F1 C1 V Sem1 P1), forall entrypoints13 : list (val * val * signature), entrypoints_compose epts12 epts23 entrypoints13 -> CompilerCorrectness.cc_simT I ExternIdents entrypoints13 F1 C1 V F3 C3 Sem1 Sem3 P1 P3 (fun f => transf23 (transf12 f)).
Theorem ccT_sim_trans: forall ExternIdents entrypoints12 I F1 C1 V F2 C2 (Sem1: CoopCoreSem (Genv.t F1 V) C1) (Sem2: CoopCoreSem (Genv.t F2 V) C2) P1 P2 transf12 (HP12: P2=transform_program transf12 P1) (SIM12: CompilerCorrectness.cc_simT I ExternIdents entrypoints12 F1 C1 V F2 C2 Sem1 Sem2 P1 P2 transf12) F3 C3 transf23 (Sem3: CoopCoreSem (Genv.t F3 V) C3) entrypoints23 P3 (SIM23:CompilerCorrectness.cc_simT I ExternIdents entrypoints23 F2 C2 V F3 C3 Sem2 Sem3 P2 P3 transf23) entrypoints13 (EPC:entrypoints_compose entrypoints12 entrypoints23 entrypoints13), CompilerCorrectness.cc_simT I ExternIdents entrypoints13 F1 C1 V F3 C3 Sem1 Sem3 P1 P3 (fun f => transf23 (transf12 f)).
Lemma coop_correctnessT_implies_cc_simT: forall ExternIdents entrypoints I F1 C1 V F2 C2 (Sem1: CoopCoreSem (Genv.t F1 V) C1) (Sem2: CoopCoreSem (Genv.t F2 V) C2) P1 P2 trans (EPC:entrypoints_compose entrypoints entrypoints entrypoints) (MAIN: In (P1.(prog_main), CompilerCorrectness.extern_func main_sig) ExternIdents), CompilerCorrectness.coop_correctnessT I ExternIdents entrypoints F1 C1 V F2 C2 Sem1 Sem2 P1 P2 trans -> CompilerCorrectness.cc_simT I ExternIdents entrypoints F1 C1 V F2 C2 Sem1 Sem2 P1 P2 trans.