10 begin |
10 begin |
11 |
11 |
12 subsection \<open>Partial version\<close> |
12 subsection \<open>Partial version\<close> |
13 |
13 |
14 definition while_option :: "('a \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a option" where |
14 definition while_option :: "('a \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a option" where |
15 "while_option b c s = (if (\<exists>k. ~ b ((c ^^ k) s)) |
15 "while_option b c s = (if (\<exists>k. \<not> b ((c ^^ k) s)) |
16 then Some ((c ^^ (LEAST k. ~ b ((c ^^ k) s))) s) |
16 then Some ((c ^^ (LEAST k. \<not> b ((c ^^ k) s))) s) |
17 else None)" |
17 else None)" |
18 |
18 |
19 theorem while_option_unfold[code]: |
19 theorem while_option_unfold[code]: |
20 "while_option b c s = (if b s then while_option b c (c s) else Some s)" |
20 "while_option b c s = (if b s then while_option b c (c s) else Some s)" |
21 proof cases |
21 proof cases |
22 assume "b s" |
22 assume "b s" |
23 show ?thesis |
23 show ?thesis |
24 proof (cases "\<exists>k. ~ b ((c ^^ k) s)") |
24 proof (cases "\<exists>k. \<not> b ((c ^^ k) s)") |
25 case True |
25 case True |
26 then obtain k where 1: "~ b ((c ^^ k) s)" .. |
26 then obtain k where 1: "\<not> b ((c ^^ k) s)" .. |
27 with \<open>b s\<close> obtain l where "k = Suc l" by (cases k) auto |
27 with \<open>b s\<close> obtain l where "k = Suc l" by (cases k) auto |
28 with 1 have "~ b ((c ^^ l) (c s))" by (auto simp: funpow_swap1) |
28 with 1 have "\<not> b ((c ^^ l) (c s))" by (auto simp: funpow_swap1) |
29 then have 2: "\<exists>l. ~ b ((c ^^ l) (c s))" .. |
29 then have 2: "\<exists>l. \<not> b ((c ^^ l) (c s))" .. |
30 from 1 |
30 from 1 |
31 have "(LEAST k. ~ b ((c ^^ k) s)) = Suc (LEAST l. ~ b ((c ^^ Suc l) s))" |
31 have "(LEAST k. \<not> b ((c ^^ k) s)) = Suc (LEAST l. \<not> b ((c ^^ Suc l) s))" |
32 by (rule Least_Suc) (simp add: \<open>b s\<close>) |
32 by (rule Least_Suc) (simp add: \<open>b s\<close>) |
33 also have "... = Suc (LEAST l. ~ b ((c ^^ l) (c s)))" |
33 also have "... = Suc (LEAST l. \<not> b ((c ^^ l) (c s)))" |
34 by (simp add: funpow_swap1) |
34 by (simp add: funpow_swap1) |
35 finally |
35 finally |
36 show ?thesis |
36 show ?thesis |
37 using True 2 \<open>b s\<close> by (simp add: funpow_swap1 while_option_def) |
37 using True 2 \<open>b s\<close> by (simp add: funpow_swap1 while_option_def) |
38 next |
38 next |
39 case False |
39 case False |
40 then have "~ (\<exists>l. ~ b ((c ^^ Suc l) s))" by blast |
40 then have "\<not> (\<exists>l. \<not> b ((c ^^ Suc l) s))" by blast |
41 then have "~ (\<exists>l. ~ b ((c ^^ l) (c s)))" |
41 then have "\<not> (\<exists>l. \<not> b ((c ^^ l) (c s)))" |
42 by (simp add: funpow_swap1) |
42 by (simp add: funpow_swap1) |
43 with False \<open>b s\<close> show ?thesis by (simp add: while_option_def) |
43 with False \<open>b s\<close> show ?thesis by (simp add: while_option_def) |
44 qed |
44 qed |
45 next |
45 next |
46 assume [simp]: "~ b s" |
46 assume [simp]: "\<not> b s" |
47 have least: "(LEAST k. ~ b ((c ^^ k) s)) = 0" |
47 have least: "(LEAST k. \<not> b ((c ^^ k) s)) = 0" |
48 by (rule Least_equality) auto |
48 by (rule Least_equality) auto |
49 moreover |
49 moreover |
50 have "\<exists>k. ~ b ((c ^^ k) s)" by (rule exI[of _ "0::nat"]) auto |
50 have "\<exists>k. \<not> b ((c ^^ k) s)" by (rule exI[of _ "0::nat"]) auto |
51 ultimately show ?thesis unfolding while_option_def by auto |
51 ultimately show ?thesis unfolding while_option_def by auto |
52 qed |
52 qed |
53 |
53 |
54 lemma while_option_stop2: |
54 lemma while_option_stop2: |
55 "while_option b c s = Some t \<Longrightarrow> EX k. t = (c^^k) s \<and> \<not> b t" |
55 "while_option b c s = Some t \<Longrightarrow> \<exists>k. t = (c^^k) s \<and> \<not> b t" |
56 apply(simp add: while_option_def split: if_splits) |
56 apply(simp add: while_option_def split: if_splits) |
57 by (metis (lifting) LeastI_ex) |
57 by (metis (lifting) LeastI_ex) |
58 |
58 |
59 lemma while_option_stop: "while_option b c s = Some t \<Longrightarrow> ~ b t" |
59 lemma while_option_stop: "while_option b c s = Some t \<Longrightarrow> \<not> b t" |
60 by(metis while_option_stop2) |
60 by(metis while_option_stop2) |
61 |
61 |
62 theorem while_option_rule: |
62 theorem while_option_rule: |
63 assumes step: "!!s. P s ==> b s ==> P (c s)" |
63 assumes step: "!!s. P s ==> b s ==> P (c s)" |
64 and result: "while_option b c s = Some t" |
64 and result: "while_option b c s = Some t" |
65 and init: "P s" |
65 and init: "P s" |
66 shows "P t" |
66 shows "P t" |
67 proof - |
67 proof - |
68 define k where "k = (LEAST k. ~ b ((c ^^ k) s))" |
68 define k where "k = (LEAST k. \<not> b ((c ^^ k) s))" |
69 from assms have t: "t = (c ^^ k) s" |
69 from assms have t: "t = (c ^^ k) s" |
70 by (simp add: while_option_def k_def split: if_splits) |
70 by (simp add: while_option_def k_def split: if_splits) |
71 have 1: "ALL i<k. b ((c ^^ i) s)" |
71 have 1: "ALL i<k. b ((c ^^ i) s)" |
72 by (auto simp: k_def dest: not_less_Least) |
72 by (auto simp: k_def dest: not_less_Least) |
73 |
73 |
74 { fix i assume "i <= k" then have "P ((c ^^ i) s)" |
74 { fix i assume "i \<le> k" then have "P ((c ^^ i) s)" |
75 by (induct i) (auto simp: init step 1) } |
75 by (induct i) (auto simp: init step 1) } |
76 thus "P t" by (auto simp: t) |
76 thus "P t" by (auto simp: t) |
77 qed |
77 qed |
78 |
78 |
79 lemma funpow_commute: |
79 lemma funpow_commute: |
262 with wf have "wf {(t,s). P s \<and> b s \<and> t = c s}" by (auto simp: wf_subset) |
262 with wf have "wf {(t,s). P s \<and> b s \<and> t = c s}" by (auto simp: wf_subset) |
263 with inv init show ?thesis by (auto simp: wf_while_option_Some) |
263 with inv init show ?thesis by (auto simp: wf_while_option_Some) |
264 qed |
264 qed |
265 |
265 |
266 theorem measure_while_option_Some: fixes f :: "'s \<Rightarrow> nat" |
266 theorem measure_while_option_Some: fixes f :: "'s \<Rightarrow> nat" |
267 shows "(!!s. P s \<Longrightarrow> b s \<Longrightarrow> P(c s) \<and> f(c s) < f s) |
267 shows "(\<And>s. P s \<Longrightarrow> b s \<Longrightarrow> P(c s) \<and> f(c s) < f s) |
268 \<Longrightarrow> P s \<Longrightarrow> EX t. while_option b c s = Some t" |
268 \<Longrightarrow> P s \<Longrightarrow> \<exists>t. while_option b c s = Some t" |
269 by(blast intro: wf_while_option_Some[OF wf_if_measure, of P b f]) |
269 by(blast intro: wf_while_option_Some[OF wf_if_measure, of P b f]) |
270 |
270 |
271 text\<open>Kleene iteration starting from the empty set and assuming some finite |
271 text\<open>Kleene iteration starting from the empty set and assuming some finite |
272 bounding set:\<close> |
272 bounding set:\<close> |
273 |
273 |