73 |
73 |
74 The compiler is a function from expressions to a list of instructions. Its |
74 The compiler is a function from expressions to a list of instructions. Its |
75 definition is obvious: |
75 definition is obvious: |
76 *} |
76 *} |
77 |
77 |
78 consts comp :: "('a,'v)expr \<Rightarrow> ('a,'v)instr list"; |
78 consts compile :: "('a,'v)expr \<Rightarrow> ('a,'v)instr list" |
79 primrec |
79 primrec |
80 "comp (Cex v) = [Const v]" |
80 "compile (Cex v) = [Const v]" |
81 "comp (Vex a) = [Load a]" |
81 "compile (Vex a) = [Load a]" |
82 "comp (Bex f e1 e2) = (comp e2) @ (comp e1) @ [Apply f]"; |
82 "compile (Bex f e1 e2) = (compile e2) @ (compile e1) @ [Apply f]" |
83 |
83 |
84 text{* |
84 text{* |
85 Now we have to prove the correctness of the compiler, i.e.\ that the |
85 Now we have to prove the correctness of the compiler, i.e.\ that the |
86 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: |
87 *} |
87 *} |
88 theorem "exec (comp e) s [] = [value e s]"; |
88 theorem "exec (compile e) s [] = [value e s]"; |
89 (*<*)oops;(*>*) |
89 (*<*)oops;(*>*) |
90 text{*\noindent |
90 text{*\noindent |
91 This theorem needs to be generalized: |
91 This theorem needs to be generalized: |
92 *} |
92 *} |
93 |
93 |
94 theorem "\<forall>vs. exec (comp e) s vs = (value e s) # vs"; |
94 theorem "\<forall>vs. exec (compile e) s vs = (value e s) # vs"; |
95 |
95 |
96 txt{*\noindent |
96 txt{*\noindent |
97 It will be proved by induction on @{term"e"} followed by simplification. |
97 It will be proved by induction on @{term"e"} followed by simplification. |
98 First, we must prove a lemma about executing the concatenation of two |
98 First, we must prove a lemma about executing the concatenation of two |
99 instruction sequences: |
99 instruction sequences: |
122 apply(induct_tac xs, simp_all split: instr.split); |
122 apply(induct_tac xs, simp_all split: instr.split); |
123 (*<*)done(*>*) |
123 (*<*)done(*>*) |
124 text{*\noindent |
124 text{*\noindent |
125 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. |
126 |
126 |
127 We could now go back and prove \isa{exec (comp e) s [] = [value e s]} |
127 We could now go back and prove @{prop"exec (compile e) s [] = [value e s]"} |
128 merely by simplification with the generalized version we just proved. |
128 merely by simplification with the generalized version we just proved. |
129 However, this is unnecessary because the generalized version fully subsumes |
129 However, this is unnecessary because the generalized version fully subsumes |
130 its instance.% |
130 its instance.% |
131 \index{compiling expressions example|)} |
131 \index{compiling expressions example|)} |
132 *} |
132 *} |
133 (*<*) |
133 (*<*) |
134 theorem "\<forall>vs. exec (comp e) s vs = (value e s) # vs"; |
134 theorem "\<forall>vs. exec (compile e) s vs = (value e s) # vs"; |
135 by(induct_tac e, auto); |
135 by(induct_tac e, auto); |
136 end |
136 end |
137 (*>*) |
137 (*>*) |