doc-src/TutorialI/CodeGen/document/CodeGen.tex
author nipkow
Mon, 09 Oct 2000 10:18:21 +0200
changeset 10171 59d6633835fa
parent 9924 3370f6aa3200
child 10187 0376cccd9118
permissions -rw-r--r--
*** empty log message ***
     1 %
     2 \begin{isabellebody}%
     3 \def\isabellecontext{CodeGen}%
     4 %
     5 \isamarkupsection{Case study: compiling expressions}
     6 %
     7 \begin{isamarkuptext}%
     8 \label{sec:ExprCompiler}
     9 The task is to develop a compiler from a generic type of expressions (built
    10 up from variables, constants and binary operations) to a stack machine.  This
    11 generic type of expressions is a generalization of the boolean expressions in
    12 \S\ref{sec:boolex}.  This time we do not commit ourselves to a particular
    13 type of variables or values but make them type parameters.  Neither is there
    14 a fixed set of binary operations: instead the expression contains the
    15 appropriate function itself.%
    16 \end{isamarkuptext}%
    17 \isacommand{types}\ {\isacharprime}v\ binop\ {\isacharequal}\ {\isachardoublequote}{\isacharprime}v\ {\isasymRightarrow}\ {\isacharprime}v\ {\isasymRightarrow}\ {\isacharprime}v{\isachardoublequote}\isanewline
    18 \isacommand{datatype}\ {\isacharparenleft}{\isacharprime}a{\isacharcomma}{\isacharprime}v{\isacharparenright}expr\ {\isacharequal}\ Cex\ {\isacharprime}v\isanewline
    19 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ {\isacharbar}\ Vex\ {\isacharprime}a\isanewline
    20 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ {\isacharbar}\ Bex\ {\isachardoublequote}{\isacharprime}v\ binop{\isachardoublequote}\ \ {\isachardoublequote}{\isacharparenleft}{\isacharprime}a{\isacharcomma}{\isacharprime}v{\isacharparenright}expr{\isachardoublequote}\ \ {\isachardoublequote}{\isacharparenleft}{\isacharprime}a{\isacharcomma}{\isacharprime}v{\isacharparenright}expr{\isachardoublequote}%
    21 \begin{isamarkuptext}%
    22 \noindent
    23 The three constructors represent constants, variables and the application of
    24 a binary operation to two subexpressions.
    25 
    26 The value of an expression w.r.t.\ an environment that maps variables to
    27 values is easily defined:%
    28 \end{isamarkuptext}%
    29 \isacommand{consts}\ value\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharparenleft}{\isacharprime}a{\isacharcomma}{\isacharprime}v{\isacharparenright}expr\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}v{\isacharparenright}\ {\isasymRightarrow}\ {\isacharprime}v{\isachardoublequote}\isanewline
    30 \isacommand{primrec}\isanewline
    31 {\isachardoublequote}value\ {\isacharparenleft}Cex\ v{\isacharparenright}\ env\ {\isacharequal}\ v{\isachardoublequote}\isanewline
    32 {\isachardoublequote}value\ {\isacharparenleft}Vex\ a{\isacharparenright}\ env\ {\isacharequal}\ env\ a{\isachardoublequote}\isanewline
    33 {\isachardoublequote}value\ {\isacharparenleft}Bex\ f\ e\isadigit{1}\ e\isadigit{2}{\isacharparenright}\ env\ {\isacharequal}\ f\ {\isacharparenleft}value\ e\isadigit{1}\ env{\isacharparenright}\ {\isacharparenleft}value\ e\isadigit{2}\ env{\isacharparenright}{\isachardoublequote}%
    34 \begin{isamarkuptext}%
    35 The stack machine has three instructions: load a constant value onto the
    36 stack, load the contents of a certain address onto the stack, and apply a
    37 binary operation to the two topmost elements of the stack, replacing them by
    38 the result. As for \isa{expr}, addresses and values are type parameters:%
    39 \end{isamarkuptext}%
    40 \isacommand{datatype}\ {\isacharparenleft}{\isacharprime}a{\isacharcomma}{\isacharprime}v{\isacharparenright}\ instr\ {\isacharequal}\ Const\ {\isacharprime}v\isanewline
    41 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ {\isacharbar}\ Load\ {\isacharprime}a\isanewline
    42 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ {\isacharbar}\ Apply\ {\isachardoublequote}{\isacharprime}v\ binop{\isachardoublequote}%
    43 \begin{isamarkuptext}%
    44 The execution of the stack machine is modelled by a function
    45 \isa{exec} that takes a list of instructions, a store (modelled as a
    46 function from addresses to values, just like the environment for
    47 evaluating expressions), and a stack (modelled as a list) of values,
    48 and returns the stack at the end of the execution---the store remains
    49 unchanged:%
    50 \end{isamarkuptext}%
    51 \isacommand{consts}\ exec\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharparenleft}{\isacharprime}a{\isacharcomma}{\isacharprime}v{\isacharparenright}instr\ list\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a{\isasymRightarrow}{\isacharprime}v{\isacharparenright}\ {\isasymRightarrow}\ {\isacharprime}v\ list\ {\isasymRightarrow}\ {\isacharprime}v\ list{\isachardoublequote}\isanewline
    52 \isacommand{primrec}\isanewline
    53 {\isachardoublequote}exec\ {\isacharbrackleft}{\isacharbrackright}\ s\ vs\ {\isacharequal}\ vs{\isachardoublequote}\isanewline
    54 {\isachardoublequote}exec\ {\isacharparenleft}i{\isacharhash}is{\isacharparenright}\ s\ vs\ {\isacharequal}\ {\isacharparenleft}case\ i\ of\isanewline
    55 \ \ \ \ Const\ v\ \ {\isasymRightarrow}\ exec\ is\ s\ {\isacharparenleft}v{\isacharhash}vs{\isacharparenright}\isanewline
    56 \ \ {\isacharbar}\ Load\ a\ \ \ {\isasymRightarrow}\ exec\ is\ s\ {\isacharparenleft}{\isacharparenleft}s\ a{\isacharparenright}{\isacharhash}vs{\isacharparenright}\isanewline
    57 \ \ {\isacharbar}\ Apply\ f\ \ {\isasymRightarrow}\ exec\ is\ s\ {\isacharparenleft}{\isacharparenleft}f\ {\isacharparenleft}hd\ vs{\isacharparenright}\ {\isacharparenleft}hd{\isacharparenleft}tl\ vs{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isacharhash}{\isacharparenleft}tl{\isacharparenleft}tl\ vs{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequote}%
    58 \begin{isamarkuptext}%
    59 \noindent
    60 Recall that \isa{hd} and \isa{tl}
    61 return the first element and the remainder of a list.
    62 Because all functions are total, \isa{hd} is defined even for the empty
    63 list, although we do not know what the result is. Thus our model of the
    64 machine always terminates properly, although the above definition does not
    65 tell us much about the result in situations where \isa{Apply} was executed
    66 with fewer than two elements on the stack.
    67 
    68 The compiler is a function from expressions to a list of instructions. Its
    69 definition is pretty much obvious:%
    70 \end{isamarkuptext}%
    71 \isacommand{consts}\ comp\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharparenleft}{\isacharprime}a{\isacharcomma}{\isacharprime}v{\isacharparenright}expr\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a{\isacharcomma}{\isacharprime}v{\isacharparenright}instr\ list{\isachardoublequote}\isanewline
    72 \isacommand{primrec}\isanewline
    73 {\isachardoublequote}comp\ {\isacharparenleft}Cex\ v{\isacharparenright}\ \ \ \ \ \ \ {\isacharequal}\ {\isacharbrackleft}Const\ v{\isacharbrackright}{\isachardoublequote}\isanewline
    74 {\isachardoublequote}comp\ {\isacharparenleft}Vex\ a{\isacharparenright}\ \ \ \ \ \ \ {\isacharequal}\ {\isacharbrackleft}Load\ a{\isacharbrackright}{\isachardoublequote}\isanewline
    75 {\isachardoublequote}comp\ {\isacharparenleft}Bex\ f\ e\isadigit{1}\ e\isadigit{2}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}comp\ e\isadigit{2}{\isacharparenright}\ {\isacharat}\ {\isacharparenleft}comp\ e\isadigit{1}{\isacharparenright}\ {\isacharat}\ {\isacharbrackleft}Apply\ f{\isacharbrackright}{\isachardoublequote}%
    76 \begin{isamarkuptext}%
    77 Now we have to prove the correctness of the compiler, i.e.\ that the
    78 execution of a compiled expression results in the value of the expression:%
    79 \end{isamarkuptext}%
    80 \isacommand{theorem}\ {\isachardoublequote}exec\ {\isacharparenleft}comp\ e{\isacharparenright}\ s\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ {\isacharbrackleft}value\ e\ s{\isacharbrackright}{\isachardoublequote}%
    81 \begin{isamarkuptext}%
    82 \noindent
    83 This theorem needs to be generalized to%
    84 \end{isamarkuptext}%
    85 \isacommand{theorem}\ {\isachardoublequote}{\isasymforall}vs{\isachardot}\ exec\ {\isacharparenleft}comp\ e{\isacharparenright}\ s\ vs\ {\isacharequal}\ {\isacharparenleft}value\ e\ s{\isacharparenright}\ {\isacharhash}\ vs{\isachardoublequote}%
    86 \begin{isamarkuptxt}%
    87 \noindent
    88 which is proved by induction on \isa{e} followed by simplification, once
    89 we have the following lemma about executing the concatenation of two
    90 instruction sequences:%
    91 \end{isamarkuptxt}%
    92 \isacommand{lemma}\ exec{\isacharunderscore}app{\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\isanewline
    93 \ \ {\isachardoublequote}{\isasymforall}vs{\isachardot}\ exec\ {\isacharparenleft}xs{\isacharat}ys{\isacharparenright}\ s\ vs\ {\isacharequal}\ exec\ ys\ s\ {\isacharparenleft}exec\ xs\ s\ vs{\isacharparenright}{\isachardoublequote}%
    94 \begin{isamarkuptxt}%
    95 \noindent
    96 This requires induction on \isa{xs} and ordinary simplification for the
    97 base cases. In the induction step, simplification leaves us with a formula
    98 that contains two \isa{case}-expressions over instructions. Thus we add
    99 automatic case splitting as well, which finishes the proof:%
   100 \end{isamarkuptxt}%
   101 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharcomma}\ simp{\isacharcomma}\ simp\ split{\isacharcolon}\ instr{\isachardot}split{\isacharparenright}%
   102 \begin{isamarkuptext}%
   103 \noindent
   104 Note that because \isaindex{auto} performs simplification, it can
   105 also be modified in the same way \isa{simp} can. Thus the proof can be
   106 rewritten as%
   107 \end{isamarkuptext}%
   108 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharcomma}\ auto\ split{\isacharcolon}\ instr{\isachardot}split{\isacharparenright}%
   109 \begin{isamarkuptext}%
   110 \noindent
   111 Although this is more compact, it is less clear for the reader of the proof.
   112 
   113 We could now go back and prove \isa{exec (comp e) s [] = [value e s]}
   114 merely by simplification with the generalized version we just proved.
   115 However, this is unnecessary because the generalized version fully subsumes
   116 its instance.%
   117 \end{isamarkuptext}%
   118 \end{isabellebody}%
   119 %%% Local Variables:
   120 %%% mode: latex
   121 %%% TeX-master: "root"
   122 %%% End: