subsubsection "Hoare Logic for Total Correctness With Logical Variables"
theory Hoare_Total_EX2 imports Hoare begin
text\<open>This is the standard set of rules that you find in many publications. In the while-rule, a logical variable is needed to remember the pre-value
of the variant (an expression that decreases by one with each iteration). In this theory, logical variables are modeled explicitly.
A simpler (but not quite as flexible) approach is found intheory\<open>Hoare_Total_EX\<close>: preand post-condition are connected via a universally quantified HOL variable.\<close>
definition hoare_tvalid :: "assn2 \ com \ assn2 \ bool"
(\<open>\<Turnstile>\<^sub>t {(1_)}/ (_)/ {(1_)}\<close> 50) where "\\<^sub>t {P}c{Q} \ (\l s. P l s \ (\t. (c,s) \ t \ Q l t))"
inductive
hoaret :: "assn2 \ com \ assn2 \ bool" (\\\<^sub>t ({(1_)}/ (_)/ {(1_)})\ 50) where
Skip: "\\<^sub>t {P} SKIP {P}" |
Assign: "\\<^sub>t {\l s. P l (s[a/x])} x::=a {P}" |
If: "\ \\<^sub>t {\l s. P l s \ bval b s} c\<^sub>1 {Q}; \\<^sub>t {\l s. P l 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: "\ \\<^sub>t {\l. P (l(x := Suc(l(x))))} c {P}; \<forall>l s. l x > 0 \<and> P l s \<longrightarrow> bval b s; \<forall>l s. l x = 0 \<and> P l s \<longrightarrow> \<not> bval b s \<rbrakk> \<Longrightarrow> \<turnstile>\<^sub>t {\<lambda>l s. \<exists>n. P (l(x:=n)) s} WHILE b DO c {\<lambda>l s. P (l(x := 0)) s}" |
conseq: "\ \l s. P' l s \ P l s; \\<^sub>t {P}c{Q}; \l s. Q l s \ Q' l s \ \ \<turnstile>\<^sub>t {P'}c{Q'}"
text\<open>Building in the consequence rule:\<close>
lemma strengthen_pre: "\ \l s. P' l s \ P l s; \\<^sub>t {P} c {Q} \ \ \\<^sub>t {P'} c {Q}" by (metis conseq)
lemma weaken_post: "\ \\<^sub>t {P} c {Q}; \l s. Q l s \ Q' l s \ \ \\<^sub>t {P} c {Q'}" by (metis conseq)
lemma Assign': "\l s. P l s \ Q l (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 x c b) have"\ l x = n; P l s \ \ \t. (WHILE b DO c, s) \ t \ P (l(x := 0)) t" for n l s proof(induction"n" arbitrary: l s) case 0 thus ?caseusing While.hyps(3) WhileFalse by (metis fun_upd_triv) next case Suc thus ?caseusing While.IH While.hyps(2) WhileTrue by (metis fun_upd_same fun_upd_triv fun_upd_upd zero_less_Suc) qed thus ?caseby fastforce next caseIfthus ?caseby auto blast qed fastforce+
definition wpt :: "com \ assn2 \ assn2" (\wp\<^sub>t\) where "wp\<^sub>t c Q = (\l s. \t. (c,s) \ t \ Q l t)"
lemma [simp]: "wp\<^sub>t (IF b THEN c\<^sub>1 ELSE c\<^sub>2) Q = (\l s. wp\<^sub>t (if bval b s then c\<^sub>1 else c\<^sub>2) Q l s)" by (auto simp: wpt_def fun_eq_iff)
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 \ assn2 \ assn2" where "wpw b c 0 Q l s = (\ bval b s \ Q l s)" | "wpw b c (Suc n) Q l s = (bval b s \ (\s'. (c,s) \ s' \ wpw b c n Q l s'))"
lemma WHILE_Its: "(WHILE b DO c,s) \ t \ Q l t \ \n. wpw b c n Q l s" proof(induction"WHILE b DO c" s t arbitrary: l rule: big_step_induct) case WhileFalse thus ?caseusing wpw.simps(1) by blast next case WhileTrue show ?case using wpw.simps(2) WhileTrue(1,2) WhileTrue(5)[OF WhileTrue(6)] by blast qed
definition support :: "assn2 \ string set" where "support P = {x. \l1 l2 s. (\y. y \ x \ l1 y = l2 y) \ P l1 s \ P l2 s}"
lemma support_wpt: "support (wp\<^sub>t c Q) \ support Q" by(simp add: support_def wpt_def) blast
lemma support_wpw0: "support (wpw b c n Q) \ support Q" proof(induction n) case 0 show ?caseby (simp add: support_def) blast next case Suc have 1: "support (\l s. A s \ B l s) \ support B" for A B by(auto simp: support_def) have 2: "support (\l s. \s'. A s s' \ B l s') \ support B" for A B by(auto simp: support_def) blast+ from Suc 1 2 show ?caseby simp (meson order_trans) qed
lemma support_wpw_Un: "support (%l. wpw b c (l x) Q l) \ insert x (UN n. support(wpw b c n Q))" using support_wpw0[of b c _ Q] apply(auto simp add: support_def subset_iff) apply metis apply metis done
lemma support_wpw: "support (%l. wpw b c (l x) Q l) \ insert x (support Q)" using support_wpw0[of b c _ Q] support_wpw_Un[of b c _ Q] by blast
lemma wpw_lupd: "x \ support Q \ wpw b c n Q (l(x := u)) = wpw b c n Q l" by(induction n) (auto simp: assn2_lupd fun_eq_iff)
lemma wpt_is_pre: "finite(support Q) \ \\<^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 c1 c2) show ?case by (auto intro:hoaret.Seq Seq finite_subset[OF support_wpt]) next caseIfthus ?caseby (auto intro:hoaret.If hoaret.conseq) next case (While b c) let ?x = "new Q" have"\x. x \ support Q" using While.prems infinite_UNIV_listI using ex_new_if_finite by blast hence [simp]: "?x \ support Q" by (rule someI_ex) let ?w = "WHILE b DO c" have fsup: "finite (support (\l. wpw b c (l x) Q l))" for x using finite_subset[OF support_wpw] While.prems by simp have c1: "\l s. wp\<^sub>t ?w Q l s \ (\n. wpw b c n Q l s)" unfolding wpt_def by (metis WHILE_Its) have c2: "\l s. l ?x = 0 \ wpw b c (l ?x) Q l s \ \ bval b s" by (simp cong: conj_cong) have w2: "\l s. 0 < l ?x \ wpw b c (l ?x) Q l s \ bval b s" by (auto simp: gr0_conv_Suc cong: conj_cong) have 1: "\l s. wpw b c (Suc(l ?x)) Q l s \
(\<exists>t. (c, s) \<Rightarrow> t \<and> wpw b c (l ?x) Q l t)" by simp have *: "\\<^sub>t {\l. wpw b c (Suc (l ?x)) Q l} c {\l. wpw b c (l ?x) Q l}" by(rule strengthen_pre[OF 1
While.IH[of "\l. wpw b c (l ?x) Q l", unfolded wpt_def, OF fsup]]) show ?case apply(rule conseq[OF _ hoaret.While[OF _ w2 c2]]) apply (simp_all add: c1 * assn2_lupd wpw_lupd del: wpw.simps(2)) done qed
lemma"\\<^sub>t
{\<lambda>l s. l ''x'' = nat(s ''x'')}
WHILE Less (N 0) (V ''x'') DO ''x'' ::= Plus (V ''x'') (N (-1))
{\<lambda>l s. s ''x'' \<le> 0}" apply(rule conseq) prefer 2 apply(rule While[where P = "\l s. l ''x'' = nat(s ''x'')" and x = "''x''"]) apply(rule Assign') apply auto done
lemma"\\<^sub>t
{\<lambda>l s. l ''x'' = 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>l s. s ''x'' \<le> 0}" apply(rule conseq) prefer 2 apply(rule While[where P = "\l s. l ''x'' = nat(s ''x'')" and x = "''x''"]) defer apply auto apply(rule Seq) prefer 2 apply(rule Seq) prefer 2 apply(rule weaken_post) apply(rule_tac P = "\l s. l ''x'' = nat(s ''x'') \ l ''y'' = nat(s ''y'')" and x = "''y''" in While) apply(rule Assign') apply auto[4] apply(rule Assign) apply(rule Assign') apply auto done
end
¤ Dauer der Verarbeitung: 0.2 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.