The Proof of Compiler Correctness

What we want to do is prove

Theorem: Let RUN be the restriction of RUN* to CMP.  Then RUN  is a homomorphism from CMP to SEM.
end

To accomplish this we will first prove the following result

Proposition:  For  any LANG1Syn-term t:

end
 
 

Definition: A StackM program is said to be well-formed if never fails to terminate because of a program error (i.e.,  because it has the wrong number or wrong type of elements on the stack for the next instruction to be performed).
A StackM program is said to be side-effect-free if it does not contain any put instructions.
A StackM program is said to be a straight-line program if it does not contain any branch instructions.
end

Fact:  If tTLANG1Syn<be> or tTLANG1Syn<ae> then hSTP(t) is a well-formed, side-effect-free, straight-line program and thus all StackM programs in CMP<be> and CMP<ae>are well-formed, side-effect-free, straight-line programs.
Proof: Left to the reader.
end

Proposition:  If p is  a well-formed, side-effect-free, straight-line program then for each k< |p|, and each choice of mStt, sVal* and rVal, there exist s'Val* and r'Val such that  run[p1pk](m,s,r,1) = <m, s's, r', k+1> and  run[p](m,s,r,1) = run[p](m, s's, r', k+1).
Proof:
end
 

Proposition: Let  be1, be2 CMP<be>, with the property that, for b{be1, be2},  if hCMP(t)= b then hSEM(t) = RUN(b), then

  1. RUN(trueCMP) = trueSEM
  2. RUN(falseCMP) = falseSEM
  3. RUN(notCMP)(be1)  = notSEM (RUN(be1))
  4. RUN(andCMP)(be1, be2)  = notSEM (RUN(be1), RUN(be2))
Proof: We proceed as follows:
i.)  By definition trueCMP = true  where, for any mStt, sVal* and rVal, we have run[true](m, s, r, 1) = < m, trues, r, 2>  whence RUN( trueCMP)(m) = <m, true> = trueSEM(m).  [ Note that "true" is overloaded in the preceeding sentence -- representing, in different contexts, a LANG1Syn-term, a StackM instruction, a StackM program, and a value from the set {true, false}.]

ii.)  Essentially the same as above.

iii.)  By definition,  notCMP(be1) =  be1toRfrRfrRnand.  By assumption,  RUN(be1):SttStt{true, false},  and, for mStt,  if RUN(be1)(m) = <m, v>  then  notSEM(RUN(be1))(m) = <m, v>.  But  then

run[be1tRfrRfrRnand](m, s, r, 1)
= run[be1toRfrRfrRnand](m, vs, r', |be1|+1)
= run[be1toRfrRfrRnand](m, s, v, |be1|+2)
= run[be1toRfrRfrRnand](m,  vs, v, |be1|+3)
= run[be1toRfrRfrRnand](m,  vvs, v, |be1|+4)
= run[be1toRfrRfrRnand](m,  nand(v, v)s, v, |be1|+5)
= run[be1toRfrRfrRnand](m, vs, v, |be1|+5)
So RUN(notCMP(be1))(m) = <m, v> =  notSEM(RUN(be))(m) as desired.

iv.)  By definition, andCMP(be1, be2) =  be1be2nandtoRfrRfrRnand.   By assumption,  RUN(be1):SttStt{true, false}, and    RUN(be2):SttStt{true, false},  and, for mStt,  if RUN(be1)(m) = <m, v> and RUN(be2)(m) = <m, w> then  andSEM(RUN(be1), RUN(be2))(m) = <m, v&w>.  But  then

run[ be1be2nandtoRfrRfrRnand](m, s, r, 1)
=  run[ be1be2nandtoRfrRfrRnand](m, vs, r, |be1|+1)
=  run[ be1be2nandtoRfrRfrRnand](m,  wvs,  r, |be1|+|be2|+1)
=  run[ be1be2nandtoRfrRfrRnand](m,  nand(w, v)s,  r, |be1|+|be2|+2)
=  run[ be1be2nandtoRfrRfrRnand](m, (w&v)s,  r, |be1|+|be2|+2)
=  run[ be1be2nandtoRfrRfrRnand](m,  s, (w&v), |be1|+|be2|+3)
=  run[ be1be2nandtoRfrRfrRnand](m, (w&v) s, (w&v), |be1|+|be2|+4)
=  run[ be1be2nandtoRfrRfrRnand](m, (w&v)(w&v) s, (w&v), |be1|+|be2|+5)
=  run[ be1be2nandtoRfrRfrRnand](m, nand( (w&v), (w&v)) s, (w&v), |be1|+|be2|+6)
=  run[ be1be2nandtoRfrRfrRnand](m,  v&ws, (w&v), |be1|+|be2|+6)
So RUN(andCMP(be1, be2))(m) = <m, v&w> = andSEM(RUN(be1),  RUN( be2))(m) as desired.
end