text\<open>This is the standard set of rules that you find in many publications.
The While-rule is different from the one in Concrete Semantics in that the
invariant is indexed by natural numbers and goes down by 1 with
every iteration. The completeness proofis easier but the rule is harder toapplyin program proofs.\<close>
definition hoare_tvalid :: "assn \ com \ assn \ bool"
(\<open>\<Turnstile>\<^sub>t {(1_)}/ (_)/ {(1_)}\<close> 50) where "\\<^sub>t {P}c{Q} \ (\s. P s \ (\t. (c,s) \ t \ Q t))"
inductive
hoaret :: "assn \ com \ assn \ bool" (\\\<^sub>t ({(1_)}/ (_)/ {(1_)})\ 50) where
If: "\ \\<^sub>t {\s. P s \ bval b s} c\<^sub>1 {Q}; \\<^sub>t {\s. P s \ \ bval b s} c\<^sub>2 {Q} \ \<Longrightarrow> \<turnstile>\<^sub>t {P} IF b THEN c\<^sub>1 ELSE c\<^sub>2 {Q}" |
While: "\ \n::nat. \\<^sub>t {P (Suc n)} c {P n}; \<forall>n s. P (Suc n) s \<longrightarrow> bval b s; \<forall>s. P 0 s \<longrightarrow> \<not> bval b s \<rbrakk> \<Longrightarrow> \<turnstile>\<^sub>t {\<lambda>s. \<exists>n. P n s} WHILE b DO c {P 0}" |
conseq: "\ \s. P' s \ P s; \\<^sub>t {P}c{Q}; \s. Q s \ Q' s \ \ \<turnstile>\<^sub>t {P'}c{Q'}"
text\<open>Building in the consequence rule:\<close>
lemma strengthen_pre: "\ \s. P' s \ P s; \\<^sub>t {P} c {Q} \ \ \\<^sub>t {P'} c {Q}" by (metis conseq)
lemma weaken_post: "\ \\<^sub>t {P} c {Q}; \s. Q s \ Q' s \ \ \\<^sub>t {P} c {Q'}" by (metis conseq)
lemma Assign': "\s. P s \ Q(s[a/x]) \ \\<^sub>t {P} x ::= a {Q}" by (simp add: strengthen_pre[OF _ Assign])
text\<open>The soundness theorem:\<close>
theorem hoaret_sound: "\\<^sub>t {P}c{Q} \ \\<^sub>t {P}c{Q}" proof(unfold hoare_tvalid_def, induction rule: hoaret.induct) case (While P c b) have"P n s \ \t. (WHILE b DO c, s) \ t \ P 0 t" for n s proof(induction"n" arbitrary: s) case 0 thus ?caseusing While.hyps(3) WhileFalse by blast next case Suc thus ?caseby (meson While.IH While.hyps(2) WhileTrue) qed thus ?caseby auto next caseIfthus ?caseby auto blast qed fastforce+
definition wpt :: "com \ assn \ assn" (\wp\<^sub>t\) where "wp\<^sub>t c Q = (\s. \t. (c,s) \ t \ Q t)"
lemma [simp]: "wp\<^sub>t (IF b THEN c\<^sub>1 ELSE c\<^sub>2) Q = (\s. wp\<^sub>t (if bval b s then c\<^sub>1 else c\<^sub>2) Q s)" apply(unfold wpt_def) apply(rule ext) apply auto done
text\<open>Function \<open>wpw\<close> computes the weakest precondition of a While-loop
that is unfolded a fixed number of times.\<close>
fun wpw :: "bexp \ com \ nat \ assn \ assn" where "wpw b c 0 Q s = (\ bval b s \ Q s)" | "wpw b c (Suc n) Q s = (bval b s \ (\s'. (c,s) \ s' \ wpw b c n Q s'))"
lemma WHILE_Its: "(WHILE b DO c,s) \ t \ Q t \ \n. wpw b c n Q s" proof(induction"WHILE b DO c" s t rule: big_step_induct) case WhileFalse thus ?caseusing wpw.simps(1) by blast next case WhileTrue thus ?caseusing wpw.simps(2) by blast qed
lemma wpt_is_pre: "\\<^sub>t {wp\<^sub>t c Q} c {Q}" proof (induction c arbitrary: Q) case SKIP show ?caseby (auto intro:hoaret.Skip) next case Assign show ?caseby (auto intro:hoaret.Assign) next case Seq thus ?caseby (auto intro:hoaret.Seq) next caseIfthus ?caseby (auto intro:hoaret.If hoaret.conseq) next case (While b c) let ?w = "WHILE b DO c" have c1: "\s. wp\<^sub>t ?w Q s \ (\n. wpw b c n Q s)" unfolding wpt_def by (metis WHILE_Its) have c3: "\s. wpw b c 0 Q s \ Q s" by simp have w2: "\n s. wpw b c (Suc n) Q s \ bval b s" by simp have w3: "\s. wpw b c 0 Q s \ \ bval b s" by simp have"\\<^sub>t {wpw b c (Suc n) Q} c {wpw b c n Q}" for n proof - have *: "\s. wpw b c (Suc n) Q s \ (\t. (c, s) \ t \ wpw b c n Q t)" by simp show ?thesis by(rule strengthen_pre[OF * While.IH[of "wpw b c n Q", unfolded wpt_def]]) qed from conseq[OF c1 hoaret.While[OF this w2 w3] c3] show ?case . qed
lemma"\\<^sub>t
{\<lambda>s. \<exists>n. n = nat(s ''x'')}
WHILE Less (N 0) (V ''x'') DO ''x'' ::= Plus (V ''x'') (N (-1))
{\<lambda>s. s ''x'' \<le> 0}" apply(rule weaken_post) apply(rule While) apply(rule Assign') apply auto done
lemma"\\<^sub>t
{\<lambda>s. \<exists>n. n = nat(s ''x'')}
WHILE Less (N 0) (V ''x'')
DO (''x'' ::= Plus (V ''x'') (N (-1));;
(''y'' ::= V ''x'';;
WHILE Less (N 0) (V ''y'') DO ''y'' ::= Plus (V ''y'') (N (-1))))
{\<lambda>s. s ''x'' \<le> 0}" apply(rule weaken_post) apply(rule While) defer apply auto[3] apply(rule Seq) prefer 2 apply(rule Seq) prefer 2 apply(rule weaken_post) apply(rule_tac P = "\m s. n = nat(s ''x'') \ m = nat(s ''y'')" in While) apply(rule Assign') apply auto[4] apply(rule Assign) apply(rule Assign') apply auto done
end
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet)
¤
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.