doc-src/TutorialI/CodeGen/CodeGen.thy
changeset 11458 09a6c44a48ea
parent 11428 332347b9b942
child 16417 9bc16273c2d4
equal deleted inserted replaced
11457:279da0358aa9 11458:09a6c44a48ea
     3 (*>*)
     3 (*>*)
     4 
     4 
     5 section{*Case Study: Compiling Expressions*}
     5 section{*Case Study: Compiling Expressions*}
     6 
     6 
     7 text{*\label{sec:ExprCompiler}
     7 text{*\label{sec:ExprCompiler}
       
     8 \index{compiling expressions example|(}%
     8 The task is to develop a compiler from a generic type of expressions (built
     9 The task is to develop a compiler from a generic type of expressions (built
     9 from variables, constants and binary operations) to a stack machine.  This
    10 from variables, constants and binary operations) to a stack machine.  This
    10 generic type of expressions is a generalization of the boolean expressions in
    11 generic type of expressions is a generalization of the boolean expressions in
    11 \S\ref{sec:boolex}.  This time we do not commit ourselves to a particular
    12 \S\ref{sec:boolex}.  This time we do not commit ourselves to a particular
    12 type of variables or values but make them type parameters.  Neither is there
    13 type of variables or values but make them type parameters.  Neither is there
    62   | Apply f  \<Rightarrow> exec is s ((f (hd vs) (hd(tl vs)))#(tl(tl vs))))";
    63   | Apply f  \<Rightarrow> exec is s ((f (hd vs) (hd(tl vs)))#(tl(tl vs))))";
    63 
    64 
    64 text{*\noindent
    65 text{*\noindent
    65 Recall that @{term"hd"} and @{term"tl"}
    66 Recall that @{term"hd"} and @{term"tl"}
    66 return the first element and the remainder of a list.
    67 return the first element and the remainder of a list.
    67 Because all functions are total, @{term"hd"} is defined even for the empty
    68 Because all functions are total, \cdx{hd} is defined even for the empty
    68 list, although we do not know what the result is. Thus our model of the
    69 list, although we do not know what the result is. Thus our model of the
    69 machine always terminates properly, although the definition above does not
    70 machine always terminates properly, although the definition above does not
    70 tell us much about the result in situations where @{term"Apply"} was executed
    71 tell us much about the result in situations where @{term"Apply"} was executed
    71 with fewer than two elements on the stack.
    72 with fewer than two elements on the stack.
    72 
    73 
    85 execution of a compiled expression results in the value of the expression:
    86 execution of a compiled expression results in the value of the expression:
    86 *}
    87 *}
    87 theorem "exec (comp e) s [] = [value e s]";
    88 theorem "exec (comp e) s [] = [value e s]";
    88 (*<*)oops;(*>*)
    89 (*<*)oops;(*>*)
    89 text{*\noindent
    90 text{*\noindent
    90 This theorem needs to be generalized to
    91 This theorem needs to be generalized:
    91 *}
    92 *}
    92 
    93 
    93 theorem "\<forall>vs. exec (comp e) s vs = (value e s) # vs";
    94 theorem "\<forall>vs. exec (comp e) s vs = (value e s) # vs";
    94 
    95 
    95 txt{*\noindent
    96 txt{*\noindent
    96 which is proved by induction on @{term"e"} followed by simplification, once
    97 It will be proved by induction on @{term"e"} followed by simplification.  
    97 we have the following lemma about executing the concatenation of two
    98 First, we must prove a lemma about executing the concatenation of two
    98 instruction sequences:
    99 instruction sequences:
    99 *}
   100 *}
   100 (*<*)oops;(*>*)
   101 (*<*)oops;(*>*)
   101 lemma exec_app[simp]:
   102 lemma exec_app[simp]:
   102   "\<forall>vs. exec (xs@ys) s vs = exec ys s (exec xs s vs)"; 
   103   "\<forall>vs. exec (xs@ys) s vs = exec ys s (exec xs s vs)"; 
   103 
   104 
   104 txt{*\noindent
   105 txt{*\noindent
   105 This requires induction on @{term"xs"} and ordinary simplification for the
   106 This requires induction on @{term"xs"} and ordinary simplification for the
   106 base cases. In the induction step, simplification leaves us with a formula
   107 base cases. In the induction step, simplification leaves us with a formula
   107 that contains two @{text"case"}-expressions over instructions. Thus we add
   108 that contains two @{text"case"}-expressions over instructions. Thus we add
   108 automatic case splitting as well, which finishes the proof:
   109 automatic case splitting, which finishes the proof:
   109 *}
   110 *}
   110 apply(induct_tac xs, simp, simp split: instr.split);
   111 apply(induct_tac xs, simp, simp split: instr.split);
   111 (*<*)done(*>*)
   112 (*<*)done(*>*)
   112 text{*\noindent
   113 text{*\noindent
   113 Note that because both \methdx{simp_all} and \methdx{auto} perform simplification, they can
   114 Note that because both \methdx{simp_all} and \methdx{auto} perform simplification, they can
   124 Although this is more compact, it is less clear for the reader of the proof.
   125 Although this is more compact, it is less clear for the reader of the proof.
   125 
   126 
   126 We could now go back and prove \isa{exec (comp e) s [] = [value e s]}
   127 We could now go back and prove \isa{exec (comp e) s [] = [value e s]}
   127 merely by simplification with the generalized version we just proved.
   128 merely by simplification with the generalized version we just proved.
   128 However, this is unnecessary because the generalized version fully subsumes
   129 However, this is unnecessary because the generalized version fully subsumes
   129 its instance.
   130 its instance.%
       
   131 \index{compiling expressions example|)}
   130 *}
   132 *}
   131 (*<*)
   133 (*<*)
   132 theorem "\<forall>vs. exec (comp e) s vs = (value e s) # vs";
   134 theorem "\<forall>vs. exec (comp e) s vs = (value e s) # vs";
   133 by(induct_tac e, auto);
   135 by(induct_tac e, auto);
   134 end
   136 end