(** Here is the separate compilation case.  Consider a nonempty list [c_units] of C source files (compilation units), [C1 ,,, Cn].  Assume that every C compilation unit [Ci] is successfully compiled by CompCert, obtaining an Asm compilation unit [Ai].  Let [asm_unit] be the nonempty list [A1 ... An].  Further assume that the C units [C1 ... Cn] can be linked together to produce a whole C program [c_program].  Then, the generated Asm units can be linked together, producing a whole Asm program [asm_program].  Moreover, [asm_program] preserves the semantics of [c_program], in the sense that there exists a backward simulation of the dynamic semantics of [asm_program] by the dynamic semantics of [c_program]. *)

Theorem separate_transf_c_program_correct:
forall c_units asm_units c_program,
nlist_forall2 (fun cu tcu => transf_c_program cu = OK tcu) c_units asm_units ->
link_list c_units = Some c_program ->
exists asm_program,
link_list asm_units = Some asm_program
/\ backward_simulation (Csem.semantics c_program) (Asm.semantics asm_program).