7 text{* Note that this definition of total validity @{text"\<Turnstile>\<^sub>t"} only |
7 text{* Note that this definition of total validity @{text"\<Turnstile>\<^sub>t"} only |
8 works if execution is deterministic (which it is in our case). *} |
8 works if execution is deterministic (which it is in our case). *} |
9 |
9 |
10 definition hoare_tvalid :: "assn \<Rightarrow> com \<Rightarrow> assn \<Rightarrow> bool" |
10 definition hoare_tvalid :: "assn \<Rightarrow> com \<Rightarrow> assn \<Rightarrow> bool" |
11 ("\<Turnstile>\<^sub>t {(1_)}/ (_)/ {(1_)}" 50) where |
11 ("\<Turnstile>\<^sub>t {(1_)}/ (_)/ {(1_)}" 50) where |
12 "\<Turnstile>\<^sub>t {P}c{Q} \<equiv> \<forall>s. P s \<longrightarrow> (\<exists>t. (c,s) \<Rightarrow> t \<and> Q t)" |
12 "\<Turnstile>\<^sub>t {P}c{Q} \<longleftrightarrow> (\<forall>s. P s \<longrightarrow> (\<exists>t. (c,s) \<Rightarrow> t \<and> Q t))" |
13 |
13 |
14 text{* Provability of Hoare triples in the proof system for total |
14 text{* Provability of Hoare triples in the proof system for total |
15 correctness is written @{text"\<turnstile>\<^sub>t {P}c{Q}"} and defined |
15 correctness is written @{text"\<turnstile>\<^sub>t {P}c{Q}"} and defined |
16 inductively. The rules for @{text"\<turnstile>\<^sub>t"} differ from those for |
16 inductively. The rules for @{text"\<turnstile>\<^sub>t"} differ from those for |
17 @{text"\<turnstile>"} only in the one place where nontermination can arise: the |
17 @{text"\<turnstile>"} only in the one place where nontermination can arise: the |
18 @{term While}-rule. *} |
18 @{term While}-rule. *} |
19 |
19 |
20 inductive |
20 inductive |
21 hoaret :: "assn \<Rightarrow> com \<Rightarrow> assn \<Rightarrow> bool" ("\<turnstile>\<^sub>t ({(1_)}/ (_)/ {(1_)})" 50) |
21 hoaret :: "assn \<Rightarrow> com \<Rightarrow> assn \<Rightarrow> bool" ("\<turnstile>\<^sub>t ({(1_)}/ (_)/ {(1_)})" 50) |
22 where |
22 where |
23 Skip: "\<turnstile>\<^sub>t {P} SKIP {P}" | |
23 |
24 Assign: "\<turnstile>\<^sub>t {\<lambda>s. P(s[a/x])} x::=a {P}" | |
24 Skip: "\<turnstile>\<^sub>t {P} SKIP {P}" | |
25 Seq: "\<lbrakk> \<turnstile>\<^sub>t {P\<^isub>1} c\<^isub>1 {P\<^isub>2}; \<turnstile>\<^sub>t {P\<^isub>2} c\<^isub>2 {P\<^isub>3} \<rbrakk> \<Longrightarrow> \<turnstile>\<^sub>t {P\<^isub>1} c\<^isub>1;;c\<^isub>2 {P\<^isub>3}" | |
25 |
|
26 Assign: "\<turnstile>\<^sub>t {\<lambda>s. P(s[a/x])} x::=a {P}" | |
|
27 |
|
28 Seq: "\<lbrakk> \<turnstile>\<^sub>t {P\<^isub>1} c\<^isub>1 {P\<^isub>2}; \<turnstile>\<^sub>t {P\<^isub>2} c\<^isub>2 {P\<^isub>3} \<rbrakk> \<Longrightarrow> \<turnstile>\<^sub>t {P\<^isub>1} c\<^isub>1;;c\<^isub>2 {P\<^isub>3}" | |
|
29 |
26 If: "\<lbrakk> \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s} c\<^isub>1 {Q}; \<turnstile>\<^sub>t {\<lambda>s. P s \<and> \<not> bval b s} c\<^isub>2 {Q} \<rbrakk> |
30 If: "\<lbrakk> \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s} c\<^isub>1 {Q}; \<turnstile>\<^sub>t {\<lambda>s. P s \<and> \<not> bval b s} c\<^isub>2 {Q} \<rbrakk> |
27 \<Longrightarrow> \<turnstile>\<^sub>t {P} IF b THEN c\<^isub>1 ELSE c\<^isub>2 {Q}" | |
31 \<Longrightarrow> \<turnstile>\<^sub>t {P} IF b THEN c\<^isub>1 ELSE c\<^isub>2 {Q}" | |
|
32 |
28 While: |
33 While: |
29 "\<lbrakk> \<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> T s n} c {\<lambda>s. P s \<and> (\<exists>n'. T s n' \<and> n' < n)} \<rbrakk> |
34 "(\<And>n::nat. |
30 \<Longrightarrow> \<turnstile>\<^sub>t {\<lambda>s. P s \<and> (\<exists>n. T s n)} WHILE b DO c {\<lambda>s. P s \<and> \<not>bval b s}" | |
35 \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> T s n} c {\<lambda>s. P s \<and> (\<exists>n'. T s n' \<and> n' < n)}) |
|
36 \<Longrightarrow> \<turnstile>\<^sub>t {\<lambda>s. P s \<and> (\<exists>n. T s n)} WHILE b DO c {\<lambda>s. P s \<and> \<not>bval b s}" | |
|
37 |
31 conseq: "\<lbrakk> \<forall>s. P' s \<longrightarrow> P s; \<turnstile>\<^sub>t {P}c{Q}; \<forall>s. Q s \<longrightarrow> Q' s \<rbrakk> \<Longrightarrow> |
38 conseq: "\<lbrakk> \<forall>s. P' s \<longrightarrow> P s; \<turnstile>\<^sub>t {P}c{Q}; \<forall>s. Q s \<longrightarrow> Q' s \<rbrakk> \<Longrightarrow> |
32 \<turnstile>\<^sub>t {P'}c{Q'}" |
39 \<turnstile>\<^sub>t {P'}c{Q'}" |
33 |
40 |
34 text{* The @{term While}-rule is like the one for partial correctness but it |
41 text{* The @{term While}-rule is like the one for partial correctness but it |
35 requires additionally that with every execution of the loop body some measure |
42 requires additionally that with every execution of the loop body some measure |
36 function @{term[source]"f :: state \<Rightarrow> nat"} decreases. *} |
43 relation @{term[source]"T :: state \<Rightarrow> nat \<Rightarrow> bool"} decreases. |
|
44 The following functional version is more intuitive: *} |
|
45 |
|
46 lemma While_fun: |
|
47 "\<lbrakk> \<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> n = f s} c {\<lambda>s. P s \<and> f s < n}\<rbrakk> |
|
48 \<Longrightarrow> \<turnstile>\<^sub>t {P} WHILE b DO c {\<lambda>s. P s \<and> \<not>bval b s}" |
|
49 by (rule While [where T="\<lambda>s n. n = f s", simplified]) |
|
50 |
|
51 text{* Building in the consequence rule: *} |
37 |
52 |
38 lemma strengthen_pre: |
53 lemma strengthen_pre: |
39 "\<lbrakk> \<forall>s. P' s \<longrightarrow> P s; \<turnstile>\<^sub>t {P} c {Q} \<rbrakk> \<Longrightarrow> \<turnstile>\<^sub>t {P'} c {Q}" |
54 "\<lbrakk> \<forall>s. P' s \<longrightarrow> P s; \<turnstile>\<^sub>t {P} c {Q} \<rbrakk> \<Longrightarrow> \<turnstile>\<^sub>t {P'} c {Q}" |
40 by (metis conseq) |
55 by (metis conseq) |
41 |
56 |
44 by (metis conseq) |
59 by (metis conseq) |
45 |
60 |
46 lemma Assign': "\<forall>s. P s \<longrightarrow> Q(s[a/x]) \<Longrightarrow> \<turnstile>\<^sub>t {P} x ::= a {Q}" |
61 lemma Assign': "\<forall>s. P s \<longrightarrow> Q(s[a/x]) \<Longrightarrow> \<turnstile>\<^sub>t {P} x ::= a {Q}" |
47 by (simp add: strengthen_pre[OF _ Assign]) |
62 by (simp add: strengthen_pre[OF _ Assign]) |
48 |
63 |
49 lemma While': |
64 lemma While_fun': |
50 assumes "\<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> T s n} c {\<lambda>s. P s \<and> (\<exists>n'. T s n' \<and> n' < n)}" |
65 assumes "\<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> n = f s} c {\<lambda>s. P s \<and> f s < n}" |
51 and "\<forall>s. P s \<and> \<not> bval b s \<longrightarrow> Q s" |
66 and "\<forall>s. P s \<and> \<not> bval b s \<longrightarrow> Q s" |
52 shows "\<turnstile>\<^sub>t {\<lambda>s. P s \<and> (\<exists>n. T s n)} WHILE b DO c {Q}" |
67 shows "\<turnstile>\<^sub>t {P} WHILE b DO c {Q}" |
53 by(blast intro: assms(1) weaken_post[OF While assms(2)]) |
68 by(blast intro: assms(1) weaken_post[OF While_fun assms(2)]) |
54 |
69 |
55 lemma While_fun: |
|
56 "\<lbrakk> \<And>n::nat. \<turnstile>\<^sub>t {\<lambda>s. P s \<and> bval b s \<and> f s = n} c {\<lambda>s. P s \<and> f s < n}\<rbrakk> |
|
57 \<Longrightarrow> \<turnstile>\<^sub>t {P} WHILE b DO c {\<lambda>s. P s \<and> \<not>bval b s}" |
|
58 by (rule While [where T="\<lambda>s n. f s = n", simplified]) |
|
59 |
70 |
60 text{* Our standard example: *} |
71 text{* Our standard example: *} |
61 |
72 |
62 lemma "\<turnstile>\<^sub>t {\<lambda>s. s ''x'' = i} ''y'' ::= N 0;; wsum {\<lambda>s. s ''y'' = sum i}" |
73 lemma "\<turnstile>\<^sub>t {\<lambda>s. s ''x'' = i} ''y'' ::= N 0;; wsum {\<lambda>s. s ''y'' = sum i}" |
63 apply(rule Seq) |
74 apply(rule Seq) |
64 prefer 2 |
75 prefer 2 |
65 apply(rule While' [where P = "\<lambda>s. (s ''y'' = sum i - sum(s ''x''))" |
76 apply(rule While_fun' [where P = "\<lambda>s. (s ''y'' = sum i - sum(s ''x''))" |
66 and T = "\<lambda>s n. n = nat(s ''x'')"]) |
77 and f = "\<lambda>s. nat(s ''x'')"]) |
67 apply(rule Seq) |
78 apply(rule Seq) |
68 prefer 2 |
79 prefer 2 |
69 apply(rule Assign) |
80 apply(rule Assign) |
70 apply(rule Assign') |
81 apply(rule Assign') |
71 apply simp |
82 apply simp |