doc-src/TutorialI/CodeGen/CodeGen.thy
changeset 8771 026f37a86ea7
parent 8744 22fa8b16c3ae
child 9458 c613cd06d5cf
equal deleted inserted replaced
8770:bfab4d4b7516 8771:026f37a86ea7
    16 datatype ('a,'v)expr = Cex 'v
    16 datatype ('a,'v)expr = Cex 'v
    17                      | Vex 'a
    17                      | Vex 'a
    18                      | Bex "'v binop"  "('a,'v)expr"  "('a,'v)expr";
    18                      | Bex "'v binop"  "('a,'v)expr"  "('a,'v)expr";
    19 
    19 
    20 text{*\noindent
    20 text{*\noindent
    21 The three constructors represent constants, variables and the combination of
    21 The three constructors represent constants, variables and the application of
    22 two subexpressions with a binary operation.
    22 a binary operation to two subexpressions.
    23 
    23 
    24 The value of an expression w.r.t.\ an environment that maps variables to
    24 The value of an expression w.r.t.\ an environment that maps variables to
    25 values is easily defined:
    25 values is easily defined:
    26 *}
    26 *}
    27 
    27 
    28 consts value :: "('a \\<Rightarrow> 'v) \\<Rightarrow> ('a,'v)expr \\<Rightarrow> 'v";
    28 consts value :: "('a,'v)expr \\<Rightarrow> ('a \\<Rightarrow> 'v) \\<Rightarrow> 'v";
    29 primrec
    29 primrec
    30 "value env (Cex v) = v"
    30 "value (Cex v) env = v"
    31 "value env (Vex a) = env a"
    31 "value (Vex a) env = env a"
    32 "value env (Bex f e1 e2) = f (value env e1) (value env e2)";
    32 "value (Bex f e1 e2) env = f (value e1 env) (value e2 env)";
    33 
    33 
    34 text{*
    34 text{*
    35 The stack machine has three instructions: load a constant value onto the
    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
    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
    37 binary operation to the two topmost elements of the stack, replacing them by
    41 datatype ('a,'v) instr = Const 'v
    41 datatype ('a,'v) instr = Const 'v
    42                        | Load 'a
    42                        | Load 'a
    43                        | Apply "'v binop";
    43                        | Apply "'v binop";
    44 
    44 
    45 text{*
    45 text{*
    46 The execution of the stack machine is modelled by a function \isa{exec}
    46 The execution of the stack machine is modelled by a function
    47 that takes a store (modelled as a function from addresses to values, just
    47 \isa{exec} that takes a list of instructions, a store (modelled as a
    48 like the environment for evaluating expressions), a stack (modelled as a
    48 function from addresses to values, just like the environment for
    49 list) of values, and a list of instructions, and returns the stack at the end
    49 evaluating expressions), and a stack (modelled as a list) of values,
    50 of the execution---the store remains unchanged:
    50 and returns the stack at the end of the execution---the store remains
       
    51 unchanged:
    51 *}
    52 *}
    52 
    53 
    53 consts exec :: "('a\\<Rightarrow>'v) \\<Rightarrow> 'v list \\<Rightarrow> ('a,'v)instr list \\<Rightarrow> 'v list";
    54 consts exec :: "('a,'v)instr list \\<Rightarrow> ('a\\<Rightarrow>'v) \\<Rightarrow> 'v list \\<Rightarrow> 'v list";
    54 primrec
    55 primrec
    55 "exec s vs [] = vs"
    56 "exec [] s vs = vs"
    56 "exec s vs (i#is) = (case i of
    57 "exec (i#is) s vs = (case i of
    57     Const v  \\<Rightarrow> exec s (v#vs) is
    58     Const v  \\<Rightarrow> exec is s (v#vs)
    58   | Load a   \\<Rightarrow> exec s ((s a)#vs) is
    59   | Load a   \\<Rightarrow> exec is s ((s a)#vs)
    59   | Apply f  \\<Rightarrow> exec s ( (f (hd vs) (hd(tl vs)))#(tl(tl vs)) ) is)";
    60   | Apply f  \\<Rightarrow> exec is s ((f (hd vs) (hd(tl vs)))#(tl(tl vs))))";
    60 
    61 
    61 text{*\noindent
    62 text{*\noindent
    62 Recall that \isa{hd} and \isa{tl}
    63 Recall that \isa{hd} and \isa{tl}
    63 return the first element and the remainder of a list.
    64 return the first element and the remainder of a list.
    64 Because all functions are total, \isa{hd} is defined even for the empty
    65 Because all functions are total, \isa{hd} is defined even for the empty
    79 
    80 
    80 text{*
    81 text{*
    81 Now we have to prove the correctness of the compiler, i.e.\ that the
    82 Now we have to prove the correctness of the compiler, i.e.\ that the
    82 execution of a compiled expression results in the value of the expression:
    83 execution of a compiled expression results in the value of the expression:
    83 *}
    84 *}
    84 theorem "exec s [] (comp e) = [value s e]";
    85 theorem "exec (comp e) s [] = [value e s]";
    85 (*<*)oops;(*>*)
    86 (*<*)oops;(*>*)
    86 text{*\noindent
    87 text{*\noindent
    87 This theorem needs to be generalized to
    88 This theorem needs to be generalized to
    88 *}
    89 *}
    89 
    90 
    90 theorem "\\<forall>vs. exec s vs (comp e) = (value s e) # vs";
    91 theorem "\\<forall>vs. exec (comp e) s vs = (value e s) # vs";
    91 
    92 
    92 txt{*\noindent
    93 txt{*\noindent
    93 which is proved by induction on \isa{e} followed by simplification, once
    94 which is proved by induction on \isa{e} followed by simplification, once
    94 we have the following lemma about executing the concatenation of two
    95 we have the following lemma about executing the concatenation of two
    95 instruction sequences:
    96 instruction sequences:
    96 *}
    97 *}
    97 (*<*)oops;(*>*)
    98 (*<*)oops;(*>*)
    98 lemma exec_app[simp]:
    99 lemma exec_app[simp]:
    99   "\\<forall>vs. exec s vs (xs@ys) = exec s (exec s vs xs) ys"; 
   100   "\\<forall>vs. exec (xs@ys) s vs = exec ys s (exec xs s vs)"; 
   100 
   101 
   101 txt{*\noindent
   102 txt{*\noindent
   102 This requires induction on \isa{xs} and ordinary simplification for the
   103 This requires induction on \isa{xs} and ordinary simplification for the
   103 base cases. In the induction step, simplification leaves us with a formula
   104 base cases. In the induction step, simplification leaves us with a formula
   104 that contains two \isa{case}-expressions over instructions. Thus we add
   105 that contains two \isa{case}-expressions over instructions. Thus we add
   111 also be modified in the same way \isa{simp} can. Thus the proof can be
   112 also be modified in the same way \isa{simp} can. Thus the proof can be
   112 rewritten as
   113 rewritten as
   113 *}
   114 *}
   114 (*<*)
   115 (*<*)
   115 lemmas [simp del] = exec_app;
   116 lemmas [simp del] = exec_app;
   116 lemma [simp]: "\\<forall>vs. exec s vs (xs@ys) = exec s (exec s vs xs) ys"; 
   117 lemma [simp]: "\\<forall>vs. exec (xs@ys) s vs = exec ys s (exec xs s vs)"; 
   117 (*>*)
   118 (*>*)
   118 apply(induct_tac xs, auto split: instr.split).;
   119 apply(induct_tac xs, auto split: instr.split).;
   119 
   120 
   120 text{*\noindent
   121 text{*\noindent
   121 Although this is more compact, it is less clear for the reader of the proof.
   122 Although this is more compact, it is less clear for the reader of the proof.
   122 
   123 
   123 We could now go back and prove \isa{exec s [] (comp e) = [value s e]}
   124 We could now go back and prove \isa{exec (comp e) s [] = [value e s]}
   124 merely by simplification with the generalized version we just proved.
   125 merely by simplification with the generalized version we just proved.
   125 However, this is unnecessary because the generalized version fully subsumes
   126 However, this is unnecessary because the generalized version fully subsumes
   126 its instance.
   127 its instance.
   127 *}
   128 *}
   128 (*<*)
   129 (*<*)
   129 theorem "\\<forall>vs. exec s vs (comp e) = (value s e) # vs";
   130 theorem "\\<forall>vs. exec (comp e) s vs = (value e s) # vs";
   130 apply(induct_tac e, auto).;
   131 apply(induct_tac e, auto).;
   131 end
   132 end
   132 (*>*)
   133 (*>*)