Section correctness.
(* We assume each instruction in P is compiled in Q according to the individual instruction compiler combined with what the linker says for branching. This is a *syntactic correctness criterion* for the whole compiled program Q *)
Variables (linker : nat -> nat) (P : nat * list X) (Q : nat * list Y)
(HPQ : forall i I, (i,I::nil) <sc P -> (linker i, icomp linker i I) <sc Q
/\ linker (1+i) = ilen I + linker i).
(* From semantic correctness of individually compiled instructions and syntactic correctness of the whole compiled program, we derive soundness and completeness of the compiled program Q wrt the source program P *)

Theorem compiler_sound i1 v1 i2 v2 w1 :
v1 ⋈ w1 /\ P /X/ (i1,v1) ->> (i2,v2)
-> exists w2, v2 ⋈ w2 /\ Q /Y/ (linker i1,w1) ->> (linker i2,w2).