equal
deleted
inserted
replaced
19 \<^dir>\<open>~~/src/HOL/Hoare\<close> and @{cite "Nipkow:1998:Winskel"}. |
19 \<^dir>\<open>~~/src/HOL/Hoare\<close> and @{cite "Nipkow:1998:Winskel"}. |
20 \<close> |
20 \<close> |
21 |
21 |
22 type_synonym 'a bexp = "'a set" |
22 type_synonym 'a bexp = "'a set" |
23 type_synonym 'a assn = "'a set" |
23 type_synonym 'a assn = "'a set" |
|
24 type_synonym 'a var = "'a \<Rightarrow> nat" |
24 |
25 |
25 datatype 'a com = |
26 datatype 'a com = |
26 Basic "'a \<Rightarrow> 'a" |
27 Basic "'a \<Rightarrow> 'a" |
27 | Seq "'a com" "'a com" ("(_;/ _)" [60, 61] 60) |
28 | Seq "'a com" "'a com" ("(_;/ _)" [60, 61] 60) |
28 | Cond "'a bexp" "'a com" "'a com" |
29 | Cond "'a bexp" "'a com" "'a com" |
29 | While "'a bexp" "'a assn" "'a com" |
30 | While "'a bexp" "'a assn" "'a var" "'a com" |
30 |
31 |
31 abbreviation Skip ("SKIP") |
32 abbreviation Skip ("SKIP") |
32 where "SKIP \<equiv> Basic id" |
33 where "SKIP \<equiv> Basic id" |
33 |
34 |
34 type_synonym 'a sem = "'a \<Rightarrow> 'a \<Rightarrow> bool" |
35 type_synonym 'a sem = "'a \<Rightarrow> 'a \<Rightarrow> bool" |
41 primrec Sem :: "'a com \<Rightarrow> 'a sem" |
42 primrec Sem :: "'a com \<Rightarrow> 'a sem" |
42 where |
43 where |
43 "Sem (Basic f) s s' \<longleftrightarrow> s' = f s" |
44 "Sem (Basic f) s s' \<longleftrightarrow> s' = f s" |
44 | "Sem (c1; c2) s s' \<longleftrightarrow> (\<exists>s''. Sem c1 s s'' \<and> Sem c2 s'' s')" |
45 | "Sem (c1; c2) s s' \<longleftrightarrow> (\<exists>s''. Sem c1 s s'' \<and> Sem c2 s'' s')" |
45 | "Sem (Cond b c1 c2) s s' \<longleftrightarrow> (if s \<in> b then Sem c1 s s' else Sem c2 s s')" |
46 | "Sem (Cond b c1 c2) s s' \<longleftrightarrow> (if s \<in> b then Sem c1 s s' else Sem c2 s s')" |
46 | "Sem (While b x c) s s' \<longleftrightarrow> (\<exists>n. iter n b (Sem c) s s')" |
47 | "Sem (While b x y c) s s' \<longleftrightarrow> (\<exists>n. iter n b (Sem c) s s')" |
47 |
48 |
48 definition Valid :: "'a bexp \<Rightarrow> 'a com \<Rightarrow> 'a bexp \<Rightarrow> bool" ("(3\<turnstile> _/ (2_)/ _)" [100, 55, 100] 50) |
49 definition Valid :: "'a bexp \<Rightarrow> 'a com \<Rightarrow> 'a bexp \<Rightarrow> bool" ("(3\<turnstile> _/ (2_)/ _)" [100, 55, 100] 50) |
49 where "\<turnstile> P c Q \<longleftrightarrow> (\<forall>s s'. Sem c s s' \<longrightarrow> s \<in> P \<longrightarrow> s' \<in> Q)" |
50 where "\<turnstile> P c Q \<longleftrightarrow> (\<forall>s s'. Sem c s s' \<longrightarrow> s \<in> P \<longrightarrow> s' \<in> Q)" |
50 |
51 |
51 lemma ValidI [intro?]: "(\<And>s s'. Sem c s s' \<Longrightarrow> s \<in> P \<Longrightarrow> s' \<in> Q) \<Longrightarrow> \<turnstile> P c Q" |
52 lemma ValidI [intro?]: "(\<And>s s'. Sem c s s' \<Longrightarrow> s \<in> P \<Longrightarrow> s' \<in> Q) \<Longrightarrow> \<turnstile> P c Q" |
145 rest is by routine application of the semantics of \<^verbatim>\<open>WHILE\<close>. |
146 rest is by routine application of the semantics of \<^verbatim>\<open>WHILE\<close>. |
146 \<close> |
147 \<close> |
147 |
148 |
148 theorem while: |
149 theorem while: |
149 assumes body: "\<turnstile> (P \<inter> b) c P" |
150 assumes body: "\<turnstile> (P \<inter> b) c P" |
150 shows "\<turnstile> P (While b X c) (P \<inter> -b)" |
151 shows "\<turnstile> P (While b X Y c) (P \<inter> -b)" |
151 proof |
152 proof |
152 fix s s' assume s: "s \<in> P" |
153 fix s s' assume s: "s \<in> P" |
153 assume "Sem (While b X c) s s'" |
154 assume "Sem (While b X Y c) s s'" |
154 then obtain n where "iter n b (Sem c) s s'" by auto |
155 then obtain n where "iter n b (Sem c) s s'" by auto |
155 from this and s show "s' \<in> P \<inter> -b" |
156 from this and s show "s' \<in> P \<inter> -b" |
156 proof (induct n arbitrary: s) |
157 proof (induct n arbitrary: s) |
157 case 0 |
158 case 0 |
158 then show ?case by auto |
159 then show ?case by auto |
205 translations |
206 translations |
206 "\<lbrace>b\<rbrace>" \<rightharpoonup> "CONST Collect (_quote b)" |
207 "\<lbrace>b\<rbrace>" \<rightharpoonup> "CONST Collect (_quote b)" |
207 "B [a/\<acute>x]" \<rightharpoonup> "\<lbrace>\<acute>(_update_name x (\<lambda>_. a)) \<in> B\<rbrace>" |
208 "B [a/\<acute>x]" \<rightharpoonup> "\<lbrace>\<acute>(_update_name x (\<lambda>_. a)) \<in> B\<rbrace>" |
208 "\<acute>x := a" \<rightharpoonup> "CONST Basic (_quote (\<acute>(_update_name x (\<lambda>_. a))))" |
209 "\<acute>x := a" \<rightharpoonup> "CONST Basic (_quote (\<acute>(_update_name x (\<lambda>_. a))))" |
209 "IF b THEN c1 ELSE c2 FI" \<rightharpoonup> "CONST Cond \<lbrace>b\<rbrace> c1 c2" |
210 "IF b THEN c1 ELSE c2 FI" \<rightharpoonup> "CONST Cond \<lbrace>b\<rbrace> c1 c2" |
210 "WHILE b INV i DO c OD" \<rightharpoonup> "CONST While \<lbrace>b\<rbrace> i c" |
211 "WHILE b INV i DO c OD" \<rightharpoonup> "CONST While \<lbrace>b\<rbrace> i (\<lambda>_. 0) c" |
211 "WHILE b DO c OD" \<rightleftharpoons> "WHILE b INV CONST undefined DO c OD" |
212 "WHILE b DO c OD" \<rightleftharpoons> "WHILE b INV CONST undefined DO c OD" |
212 |
213 |
213 parse_translation \<open> |
214 parse_translation \<open> |
214 let |
215 let |
215 fun quote_tr [t] = Syntax_Trans.quote_tr \<^syntax_const>\<open>_antiquote\<close> t |
216 fun quote_tr [t] = Syntax_Trans.quote_tr \<^syntax_const>\<open>_antiquote\<close> t |
333 \<Longrightarrow> \<turnstile> \<lbrace>\<acute>P\<rbrace> IF \<acute>b THEN c1 ELSE c2 FI Q" |
334 \<Longrightarrow> \<turnstile> \<lbrace>\<acute>P\<rbrace> IF \<acute>b THEN c1 ELSE c2 FI Q" |
334 by (rule cond) (simp_all add: Valid_def) |
335 by (rule cond) (simp_all add: Valid_def) |
335 |
336 |
336 text \<open>While statements --- with optional invariant.\<close> |
337 text \<open>While statements --- with optional invariant.\<close> |
337 |
338 |
338 lemma [intro?]: "\<turnstile> (P \<inter> b) c P \<Longrightarrow> \<turnstile> P (While b P c) (P \<inter> -b)" |
339 lemma [intro?]: "\<turnstile> (P \<inter> b) c P \<Longrightarrow> \<turnstile> P (While b P V c) (P \<inter> -b)" |
339 by (rule while) |
340 by (rule while) |
340 |
341 |
341 lemma [intro?]: "\<turnstile> (P \<inter> b) c P \<Longrightarrow> \<turnstile> P (While b undefined c) (P \<inter> -b)" |
342 lemma [intro?]: "\<turnstile> (P \<inter> b) c P \<Longrightarrow> \<turnstile> P (While b undefined V c) (P \<inter> -b)" |
342 by (rule while) |
343 by (rule while) |
343 |
344 |
344 |
345 |
345 lemma [intro?]: |
346 lemma [intro?]: |
346 "\<turnstile> \<lbrace>\<acute>P \<and> \<acute>b\<rbrace> c \<lbrace>\<acute>P\<rbrace> |
347 "\<turnstile> \<lbrace>\<acute>P \<and> \<acute>b\<rbrace> c \<lbrace>\<acute>P\<rbrace> |
385 "\<forall>s s'. Sem c s s' \<longrightarrow> s \<in> I \<and> s \<in> b \<longrightarrow> s' \<in> I \<Longrightarrow> |
386 "\<forall>s s'. Sem c s s' \<longrightarrow> s \<in> I \<and> s \<in> b \<longrightarrow> s' \<in> I \<Longrightarrow> |
386 (\<And>s s'. s \<in> I \<Longrightarrow> iter n b (Sem c) s s' \<Longrightarrow> s' \<in> I \<and> s' \<notin> b)" |
387 (\<And>s s'. s \<in> I \<Longrightarrow> iter n b (Sem c) s s' \<Longrightarrow> s' \<in> I \<and> s' \<notin> b)" |
387 by (induct n) auto |
388 by (induct n) auto |
388 |
389 |
389 lemma WhileRule: |
390 lemma WhileRule: |
390 "p \<subseteq> i \<Longrightarrow> Valid (i \<inter> b) c i \<Longrightarrow> i \<inter> (-b) \<subseteq> q \<Longrightarrow> Valid p (While b i c) q" |
391 "p \<subseteq> i \<Longrightarrow> Valid (i \<inter> b) c i \<Longrightarrow> i \<inter> (-b) \<subseteq> q \<Longrightarrow> Valid p (While b i v c) q" |
391 apply (clarsimp simp: Valid_def) |
392 apply (clarsimp simp: Valid_def) |
392 apply (drule iter_aux) |
393 apply (drule iter_aux) |
393 prefer 2 |
394 prefer 2 |
394 apply assumption |
395 apply assumption |
395 apply blast |
396 apply blast |
398 |
399 |
399 lemma Compl_Collect: "- Collect b = {x. \<not> b x}" |
400 lemma Compl_Collect: "- Collect b = {x. \<not> b x}" |
400 by blast |
401 by blast |
401 |
402 |
402 lemmas AbortRule = SkipRule \<comment> \<open>dummy version\<close> |
403 lemmas AbortRule = SkipRule \<comment> \<open>dummy version\<close> |
|
404 lemmas SeqRuleTC = SkipRule \<comment> \<open>dummy version\<close> |
|
405 lemmas SkipRuleTC = SkipRule \<comment> \<open>dummy version\<close> |
|
406 lemmas BasicRuleTC = SkipRule \<comment> \<open>dummy version\<close> |
|
407 lemmas CondRuleTC = SkipRule \<comment> \<open>dummy version\<close> |
|
408 lemmas WhileRuleTC = SkipRule \<comment> \<open>dummy version\<close> |
403 |
409 |
404 ML_file \<open>~~/src/HOL/Hoare/hoare_tac.ML\<close> |
410 ML_file \<open>~~/src/HOL/Hoare/hoare_tac.ML\<close> |
405 |
411 |
406 method_setup hoare = |
412 method_setup hoare = |
407 \<open>Scan.succeed (fn ctxt => |
413 \<open>Scan.succeed (fn ctxt => |