# HG changeset patch # User nipkow # Date 1370080961 -7200 # Node ID c79a3e15779e2f4a85009380b58a10dae6e683d5 # Parent 780b3870319f93fc1de975e3ab38177fb75b85d9 tuned theory name diff -r 780b3870319f -r c79a3e15779e src/HOL/IMP/HoareT.thy --- a/src/HOL/IMP/HoareT.thy Sat Jun 01 11:48:06 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,214 +0,0 @@ -(* Author: Tobias Nipkow *) - -theory HoareT imports Hoare_Sound_Complete Hoare_Examples begin - -subsection "Hoare Logic for Total Correctness" - -text{* Note that this definition of total validity @{text"\\<^sub>t"} only -works if execution is deterministic (which it is in our case). *} - -definition hoare_tvalid :: "assn \ com \ assn \ bool" - ("\\<^sub>t {(1_)}/ (_)/ {(1_)}" 50) where -"\\<^sub>t {P}c{Q} \ (\s. P s \ (\t. (c,s) \ t \ Q t))" - -text{* Provability of Hoare triples in the proof system for total -correctness is written @{text"\\<^sub>t {P}c{Q}"} and defined -inductively. The rules for @{text"\\<^sub>t"} differ from those for -@{text"\"} only in the one place where nontermination can arise: the -@{term While}-rule. *} - -inductive - hoaret :: "assn \ com \ assn \ bool" ("\\<^sub>t ({(1_)}/ (_)/ {(1_)})" 50) -where - -Skip: "\\<^sub>t {P} SKIP {P}" | - -Assign: "\\<^sub>t {\s. P(s[a/x])} x::=a {P}" | - -Seq: "\ \\<^sub>t {P\<^isub>1} c\<^isub>1 {P\<^isub>2}; \\<^sub>t {P\<^isub>2} c\<^isub>2 {P\<^isub>3} \ \ \\<^sub>t {P\<^isub>1} c\<^isub>1;;c\<^isub>2 {P\<^isub>3}" | - -If: "\ \\<^sub>t {\s. P s \ bval b s} c\<^isub>1 {Q}; \\<^sub>t {\s. P s \ \ bval b s} c\<^isub>2 {Q} \ - \ \\<^sub>t {P} IF b THEN c\<^isub>1 ELSE c\<^isub>2 {Q}" | - -While: - "(\n::nat. - \\<^sub>t {\s. P s \ bval b s \ T s n} c {\s. P s \ (\n'. T s n' \ n' < n)}) - \ \\<^sub>t {\s. P s \ (\n. T s n)} WHILE b DO c {\s. P s \ \bval b s}" | - -conseq: "\ \s. P' s \ P s; \\<^sub>t {P}c{Q}; \s. Q s \ Q' s \ \ - \\<^sub>t {P'}c{Q'}" - -text{* The @{term While}-rule is like the one for partial correctness but it -requires additionally that with every execution of the loop body some measure -relation @{term[source]"T :: state \ nat \ bool"} decreases. -The following functional version is more intuitive: *} - -lemma While_fun: - "\ \n::nat. \\<^sub>t {\s. P s \ bval b s \ n = f s} c {\s. P s \ f s < n}\ - \ \\<^sub>t {P} WHILE b DO c {\s. P s \ \bval b s}" - by (rule While [where T="\s n. n = f s", simplified]) - -text{* Building in the consequence rule: *} - -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]) - -lemma While_fun': -assumes "\n::nat. \\<^sub>t {\s. P s \ bval b s \ n = f s} c {\s. P s \ f s < n}" - and "\s. P s \ \ bval b s \ Q s" -shows "\\<^sub>t {P} WHILE b DO c {Q}" -by(blast intro: assms(1) weaken_post[OF While_fun assms(2)]) - - -text{* Our standard example: *} - -lemma "\\<^sub>t {\s. s ''x'' = i} ''y'' ::= N 0;; wsum {\s. s ''y'' = sum i}" -apply(rule Seq) - prefer 2 - apply(rule While_fun' [where P = "\s. (s ''y'' = sum i - sum(s ''x''))" - and f = "\s. nat(s ''x'')"]) - apply(rule Seq) - prefer 2 - apply(rule Assign) - apply(rule Assign') - apply simp - apply(simp add: minus_numeral_simps(1)[symmetric] del: minus_numeral_simps) - apply(simp) -apply(rule Assign') -apply simp -done - - -text{* The soundness theorem: *} - -theorem hoaret_sound: "\\<^sub>t {P}c{Q} \ \\<^sub>t {P}c{Q}" -proof(unfold hoare_tvalid_def, induct rule: hoaret.induct) - case (While P b T c) - { - fix s n - have "\ P s; T s n \ \ \t. (WHILE b DO c, s) \ t \ P t \ \ bval b t" - proof(induction "n" arbitrary: s rule: less_induct) - case (less n) - thus ?case by (metis While(2) WhileFalse WhileTrue) - qed - } - thus ?case by auto -next - case If thus ?case by auto blast -qed fastforce+ - - -text{* -The completeness proof proceeds along the same lines as the one for partial -correctness. First we have to strengthen our notion of weakest precondition -to take termination into account: *} - -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 SKIP Q = Q" -by(auto intro!: ext simp: wpt_def) - -lemma [simp]: "wp\<^sub>t (x ::= e) Q = (\s. Q(s(x := aval e s)))" -by(auto intro!: ext simp: wpt_def) - -lemma [simp]: "wp\<^sub>t (c\<^isub>1;;c\<^isub>2) Q = wp\<^sub>t c\<^isub>1 (wp\<^sub>t c\<^isub>2 Q)" -unfolding wpt_def -apply(rule ext) -apply auto -done - -lemma [simp]: - "wp\<^sub>t (IF b THEN c\<^isub>1 ELSE c\<^isub>2) Q = (\s. wp\<^sub>t (if bval b s then c\<^isub>1 else c\<^isub>2) Q s)" -apply(unfold wpt_def) -apply(rule ext) -apply auto -done - - -text{* Now we define the number of iterations @{term "WHILE b DO c"} needs to -terminate when started in state @{text s}. Because this is a truly partial -function, we define it as an (inductive) relation first: *} - -inductive Its :: "bexp \ com \ state \ nat \ bool" where -Its_0: "\ bval b s \ Its b c s 0" | -Its_Suc: "\ bval b s; (c,s) \ s'; Its b c s' n \ \ Its b c s (Suc n)" - -text{* The relation is in fact a function: *} - -lemma Its_fun: "Its b c s n \ Its b c s n' \ n=n'" -proof(induction arbitrary: n' rule:Its.induct) - case Its_0 thus ?case by(metis Its.cases) -next - case Its_Suc thus ?case by(metis Its.cases big_step_determ) -qed - -text{* For all terminating loops, @{const Its} yields a result: *} - -lemma WHILE_Its: "(WHILE b DO c,s) \ t \ \n. Its b c s n" -proof(induction "WHILE b DO c" s t rule: big_step_induct) - case WhileFalse thus ?case by (metis Its_0) -next - case WhileTrue thus ?case by (metis Its_Suc) -qed - -lemma wpt_is_pre: "\\<^sub>t {wp\<^sub>t c Q} c {Q}" -proof (induction c arbitrary: Q) - case SKIP show ?case by simp (blast intro:hoaret.Skip) -next - case Assign show ?case by simp (blast intro:hoaret.Assign) -next - case Seq thus ?case by simp (blast intro:hoaret.Seq) -next - case If thus ?case by simp (blast intro:hoaret.If hoaret.conseq) -next - case (While b c) - let ?w = "WHILE b DO c" - let ?T = "Its b c" - have "\s. wp\<^sub>t (WHILE b DO c) Q s \ wp\<^sub>t (WHILE b DO c) Q s \ (\n. Its b c s n)" - unfolding wpt_def by (metis WHILE_Its) - moreover - { fix n - { fix s t - assume "bval b s" "?T s n" "(?w, s) \ t" "Q t" - from `bval b s` `(?w, s) \ t` obtain s' where - "(c,s) \ s'" "(?w,s') \ t" by auto - from `(?w, s') \ t` obtain n'' where "?T s' n''" by (blast dest: WHILE_Its) - with `bval b s` `(c, s) \ s'` - have "?T s (Suc n'')" by (rule Its_Suc) - with `?T s n` have "n = Suc n''" by (rule Its_fun) - with `(c,s) \ s'` `(?w,s') \ t` `Q t` `?T s' n''` - have "wp\<^sub>t c (\s'. wp\<^sub>t ?w Q s' \ (\n'. ?T s' n' \ n' < n)) s" - by (auto simp: wpt_def) - } - hence "\s. wp\<^sub>t ?w Q s \ bval b s \ ?T s n \ - wp\<^sub>t c (\s'. wp\<^sub>t ?w Q s' \ (\n'. ?T s' n' \ n' < n)) s" - unfolding wpt_def by auto - (* by (metis WhileE Its_Suc Its_fun WHILE_Its lessI) *) - note strengthen_pre[OF this While] - } note hoaret.While[OF this] - moreover have "\s. wp\<^sub>t ?w Q s \ \ bval b s \ Q s" by (auto simp add:wpt_def) - ultimately show ?case by (rule conseq) -qed - - -text{*\noindent In the @{term While}-case, @{const Its} provides the obvious -termination argument. - -The actual completeness theorem follows directly, in the same manner -as for partial correctness: *} - -theorem hoaret_complete: "\\<^sub>t {P}c{Q} \ \\<^sub>t {P}c{Q}" -apply(rule strengthen_pre[OF _ wpt_is_pre]) -apply(auto simp: hoare_tvalid_def hoare_valid_def wpt_def) -done - -end diff -r 780b3870319f -r c79a3e15779e src/HOL/IMP/Hoare_Total.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/IMP/Hoare_Total.thy Sat Jun 01 12:02:41 2013 +0200 @@ -0,0 +1,214 @@ +(* Author: Tobias Nipkow *) + +theory Hoare_Total imports Hoare_Sound_Complete Hoare_Examples begin + +subsection "Hoare Logic for Total Correctness" + +text{* Note that this definition of total validity @{text"\\<^sub>t"} only +works if execution is deterministic (which it is in our case). *} + +definition hoare_tvalid :: "assn \ com \ assn \ bool" + ("\\<^sub>t {(1_)}/ (_)/ {(1_)}" 50) where +"\\<^sub>t {P}c{Q} \ (\s. P s \ (\t. (c,s) \ t \ Q t))" + +text{* Provability of Hoare triples in the proof system for total +correctness is written @{text"\\<^sub>t {P}c{Q}"} and defined +inductively. The rules for @{text"\\<^sub>t"} differ from those for +@{text"\"} only in the one place where nontermination can arise: the +@{term While}-rule. *} + +inductive + hoaret :: "assn \ com \ assn \ bool" ("\\<^sub>t ({(1_)}/ (_)/ {(1_)})" 50) +where + +Skip: "\\<^sub>t {P} SKIP {P}" | + +Assign: "\\<^sub>t {\s. P(s[a/x])} x::=a {P}" | + +Seq: "\ \\<^sub>t {P\<^isub>1} c\<^isub>1 {P\<^isub>2}; \\<^sub>t {P\<^isub>2} c\<^isub>2 {P\<^isub>3} \ \ \\<^sub>t {P\<^isub>1} c\<^isub>1;;c\<^isub>2 {P\<^isub>3}" | + +If: "\ \\<^sub>t {\s. P s \ bval b s} c\<^isub>1 {Q}; \\<^sub>t {\s. P s \ \ bval b s} c\<^isub>2 {Q} \ + \ \\<^sub>t {P} IF b THEN c\<^isub>1 ELSE c\<^isub>2 {Q}" | + +While: + "(\n::nat. + \\<^sub>t {\s. P s \ bval b s \ T s n} c {\s. P s \ (\n'. T s n' \ n' < n)}) + \ \\<^sub>t {\s. P s \ (\n. T s n)} WHILE b DO c {\s. P s \ \bval b s}" | + +conseq: "\ \s. P' s \ P s; \\<^sub>t {P}c{Q}; \s. Q s \ Q' s \ \ + \\<^sub>t {P'}c{Q'}" + +text{* The @{term While}-rule is like the one for partial correctness but it +requires additionally that with every execution of the loop body some measure +relation @{term[source]"T :: state \ nat \ bool"} decreases. +The following functional version is more intuitive: *} + +lemma While_fun: + "\ \n::nat. \\<^sub>t {\s. P s \ bval b s \ n = f s} c {\s. P s \ f s < n}\ + \ \\<^sub>t {P} WHILE b DO c {\s. P s \ \bval b s}" + by (rule While [where T="\s n. n = f s", simplified]) + +text{* Building in the consequence rule: *} + +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]) + +lemma While_fun': +assumes "\n::nat. \\<^sub>t {\s. P s \ bval b s \ n = f s} c {\s. P s \ f s < n}" + and "\s. P s \ \ bval b s \ Q s" +shows "\\<^sub>t {P} WHILE b DO c {Q}" +by(blast intro: assms(1) weaken_post[OF While_fun assms(2)]) + + +text{* Our standard example: *} + +lemma "\\<^sub>t {\s. s ''x'' = i} ''y'' ::= N 0;; wsum {\s. s ''y'' = sum i}" +apply(rule Seq) + prefer 2 + apply(rule While_fun' [where P = "\s. (s ''y'' = sum i - sum(s ''x''))" + and f = "\s. nat(s ''x'')"]) + apply(rule Seq) + prefer 2 + apply(rule Assign) + apply(rule Assign') + apply simp + apply(simp add: minus_numeral_simps(1)[symmetric] del: minus_numeral_simps) + apply(simp) +apply(rule Assign') +apply simp +done + + +text{* The soundness theorem: *} + +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 b T c) + { + fix s n + have "\ P s; T s n \ \ \t. (WHILE b DO c, s) \ t \ P t \ \ bval b t" + proof(induction "n" arbitrary: s rule: less_induct) + case (less n) + thus ?case by (metis While.IH WhileFalse WhileTrue) + qed + } + thus ?case by auto +next + case If thus ?case by auto blast +qed fastforce+ + + +text{* +The completeness proof proceeds along the same lines as the one for partial +correctness. First we have to strengthen our notion of weakest precondition +to take termination into account: *} + +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 SKIP Q = Q" +by(auto intro!: ext simp: wpt_def) + +lemma [simp]: "wp\<^sub>t (x ::= e) Q = (\s. Q(s(x := aval e s)))" +by(auto intro!: ext simp: wpt_def) + +lemma [simp]: "wp\<^sub>t (c\<^isub>1;;c\<^isub>2) Q = wp\<^sub>t c\<^isub>1 (wp\<^sub>t c\<^isub>2 Q)" +unfolding wpt_def +apply(rule ext) +apply auto +done + +lemma [simp]: + "wp\<^sub>t (IF b THEN c\<^isub>1 ELSE c\<^isub>2) Q = (\s. wp\<^sub>t (if bval b s then c\<^isub>1 else c\<^isub>2) Q s)" +apply(unfold wpt_def) +apply(rule ext) +apply auto +done + + +text{* Now we define the number of iterations @{term "WHILE b DO c"} needs to +terminate when started in state @{text s}. Because this is a truly partial +function, we define it as an (inductive) relation first: *} + +inductive Its :: "bexp \ com \ state \ nat \ bool" where +Its_0: "\ bval b s \ Its b c s 0" | +Its_Suc: "\ bval b s; (c,s) \ s'; Its b c s' n \ \ Its b c s (Suc n)" + +text{* The relation is in fact a function: *} + +lemma Its_fun: "Its b c s n \ Its b c s n' \ n=n'" +proof(induction arbitrary: n' rule:Its.induct) + case Its_0 thus ?case by(metis Its.cases) +next + case Its_Suc thus ?case by(metis Its.cases big_step_determ) +qed + +text{* For all terminating loops, @{const Its} yields a result: *} + +lemma WHILE_Its: "(WHILE b DO c,s) \ t \ \n. Its b c s n" +proof(induction "WHILE b DO c" s t rule: big_step_induct) + case WhileFalse thus ?case by (metis Its_0) +next + case WhileTrue thus ?case by (metis Its_Suc) +qed + +lemma wpt_is_pre: "\\<^sub>t {wp\<^sub>t c Q} c {Q}" +proof (induction c arbitrary: Q) + case SKIP show ?case by simp (blast intro:hoaret.Skip) +next + case Assign show ?case by simp (blast intro:hoaret.Assign) +next + case Seq thus ?case by simp (blast intro:hoaret.Seq) +next + case If thus ?case by simp (blast intro:hoaret.If hoaret.conseq) +next + case (While b c) + let ?w = "WHILE b DO c" + let ?T = "Its b c" + have "\s. wp\<^sub>t (WHILE b DO c) Q s \ wp\<^sub>t (WHILE b DO c) Q s \ (\n. Its b c s n)" + unfolding wpt_def by (metis WHILE_Its) + moreover + { fix n + { fix s t + assume "bval b s" "?T s n" "(?w, s) \ t" "Q t" + from `bval b s` `(?w, s) \ t` obtain s' where + "(c,s) \ s'" "(?w,s') \ t" by auto + from `(?w, s') \ t` obtain n'' where "?T s' n''" by (blast dest: WHILE_Its) + with `bval b s` `(c, s) \ s'` + have "?T s (Suc n'')" by (rule Its_Suc) + with `?T s n` have "n = Suc n''" by (rule Its_fun) + with `(c,s) \ s'` `(?w,s') \ t` `Q t` `?T s' n''` + have "wp\<^sub>t c (\s'. wp\<^sub>t ?w Q s' \ (\n'. ?T s' n' \ n' < n)) s" + by (auto simp: wpt_def) + } + hence "\s. wp\<^sub>t ?w Q s \ bval b s \ ?T s n \ + wp\<^sub>t c (\s'. wp\<^sub>t ?w Q s' \ (\n'. ?T s' n' \ n' < n)) s" + unfolding wpt_def by auto + (* by (metis WhileE Its_Suc Its_fun WHILE_Its lessI) *) + note strengthen_pre[OF this While] + } note hoaret.While[OF this] + moreover have "\s. wp\<^sub>t ?w Q s \ \ bval b s \ Q s" by (auto simp add:wpt_def) + ultimately show ?case by (rule conseq) +qed + + +text{*\noindent In the @{term While}-case, @{const Its} provides the obvious +termination argument. + +The actual completeness theorem follows directly, in the same manner +as for partial correctness: *} + +theorem hoaret_complete: "\\<^sub>t {P}c{Q} \ \\<^sub>t {P}c{Q}" +apply(rule strengthen_pre[OF _ wpt_is_pre]) +apply(auto simp: hoare_tvalid_def hoare_valid_def wpt_def) +done + +end diff -r 780b3870319f -r c79a3e15779e src/HOL/ROOT --- a/src/HOL/ROOT Sat Jun 01 11:48:06 2013 +0200 +++ b/src/HOL/ROOT Sat Jun 01 12:02:41 2013 +0200 @@ -130,7 +130,7 @@ Live_True Hoare_Examples VCG - HoareT + Hoare_Total Collecting1 Collecting_Examples Abs_Int_Tests