Correctness of a simple expression/stack-machine compiler.
*)
section \<open>Correctness of a simple expression compiler\<close>
theory Expr_Compiler imports Main begin
text\<open>
This is a (rather trivial) example of program verification. We model a
compiler for translating expressions to stack machine instructions, and
prove its correctness wrt.\ some evaluation semantics. \<close>
subsection \<open>Binary operations\<close>
text\<open>
Binary operations are just functions over some type of values. This is both for abstract syntaxand semantics, i.e.\ we use a ``shallow embedding''
here. \<close>
text\<open>
The language of expressions is defined as an inductive type, consisting of
variables, constants, and binary operations on expressions. \<close>
text\<open>
The main result of this development is the correctness theoremfor \<open>compile\<close>. We first establish a lemma about \<open>exec\<close> and list append. \<close>
lemma exec_append: "exec (xs @ ys) stack env =
exec ys (exec xs stack env) env" proof (induct xs arbitrary: stack) case Nil show ?caseby simp next case (Cons x xs) show ?case proof (induct x) case Const from Cons show ?caseby simp next case Load from Cons show ?caseby simp next caseApply from Cons show ?caseby simp qed qed
theorem correctness: "execute (compile e) env = eval e env" proof - have"\stack. exec (compile e) stack env = eval e env # stack" proof (induct e) case Variable show ?caseby simp next case Constant show ?caseby simp next case Binop thenshow ?caseby (simp add: exec_append) qed thenshow ?thesis by (simp add: execute_def) qed
text\<open> \<^bigskip> In the proofs above, the \<open>simp\<close> method does quite a lot of work behind the
scenes (mostly ``functional program execution''). Subsequently, the same
reasoning is elaborated in detail --- at most one recursive function definitionis used at a time. Thus we get a better idea of what is actually
going on. \<close>
lemma exec_append': "exec (xs @ ys) stack env = exec ys (exec xs stack env) env" proof (induct xs arbitrary: stack) case (Nil s) have"exec ([] @ ys) s env = exec ys s env" by simp alsohave"\ = exec ys (exec [] s env) env" by simp finallyshow ?case . next case (Cons x xs s) show ?case proof (induct x) case (Const val) have"exec ((Const val # xs) @ ys) s env = exec (Const val # xs @ ys) s env" by simp alsohave"\ = exec (xs @ ys) (val # s) env" by simp alsofrom Cons have"\ = exec ys (exec xs (val # s) env) env" . alsohave"\ = exec ys (exec (Const val # xs) s env) env" by simp finallyshow ?case . next case (Load adr) from Cons show ?case by simp \<comment> \<open>same as above\<close> next case (Apply fn) have"exec ((Apply fn # xs) @ ys) s env =
exec (Apply fn # xs @ ys) s env" by simp alsohave"\ =
exec (xs @ ys) (fn (hd s) (hd (tl s)) # (tl (tl s))) env" by simp alsofrom Cons have"\ =
exec ys (exec xs (fn (hd s) (hd (tl s)) # tl (tl s)) env) env" . alsohave"\ = exec ys (exec (Apply fn # xs) s env) env" by simp finallyshow ?case . qed qed
theorem correctness': "execute (compile e) env = eval e env" proof - have exec_compile: "\stack. exec (compile e) stack env = eval e env # stack" proof (induct e) case (Variable adr s) have"exec (compile (Variable adr)) s env = exec [Load adr] s env" by simp alsohave"\ = env adr # s" by simp alsohave"env adr = eval (Variable adr) env" by simp finallyshow ?case . next case (Constant val s) show ?caseby simp \<comment> \<open>same as above\<close> next case (Binop fn e1 e2 s) have"exec (compile (Binop fn e1 e2)) s env =
exec (compile e2 @ compile e1 @ [Apply fn]) s env" by simp alsohave"\ = exec [Apply fn]
(exec (compile e1) (exec (compile e2) s env) env) env" by (simp only: exec_append) alsohave"exec (compile e2) s env = eval e2 env # s" by fact alsohave"exec (compile e1) \ env = eval e1 env # \" by fact alsohave"exec [Apply fn] \ env =
fn (hd \<dots>) (hd (tl \<dots>)) # (tl (tl \<dots>))" by simp alsohave"\ = fn (eval e1 env) (eval e2 env) # s" by simp alsohave"fn (eval e1 env) (eval e2 env) =
eval (Binop fn e1 e2) env" by simp finallyshow ?case . qed
have"execute (compile e) env = hd (exec (compile e) [] env)" by (simp add: execute_def) alsofrom exec_compile have"exec (compile e) [] env = [eval e env]" . alsohave"hd \ = eval e env" by simp finallyshow ?thesis . qed
end
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.15Bemerkung:
Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.