| author | wenzelm | 
| Tue, 08 Nov 2011 12:03:51 +0100 | |
| changeset 45405 | 23e5af70af07 | 
| parent 41764 | 5268aef2fe83 | 
| child 45834 | 9c232d370244 | 
| permissions | -rw-r--r-- | 
| 22803 | 1 | (* Title: HOL/Library/While_Combinator.thy | 
| 10251 | 2 | Author: Tobias Nipkow | 
| 37757 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 3 | Author: Alexander Krauss | 
| 10251 | 4 | Copyright 2000 TU Muenchen | 
| 5 | *) | |
| 6 | ||
| 14706 | 7 | header {* A general ``while'' combinator *}
 | 
| 10251 | 8 | |
| 15131 | 9 | theory While_Combinator | 
| 30738 | 10 | imports Main | 
| 15131 | 11 | begin | 
| 10251 | 12 | |
| 37760 | 13 | subsection {* Partial version *}
 | 
| 37757 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 14 | |
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 15 | definition while_option :: "('a \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a option" where
 | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 16 | "while_option b c s = (if (\<exists>k. ~ b ((c ^^ k) s)) | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 17 | then Some ((c ^^ (LEAST k. ~ b ((c ^^ k) s))) s) | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 18 | else None)" | 
| 10251 | 19 | |
| 37757 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 20 | theorem while_option_unfold[code]: | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 21 | "while_option b c s = (if b s then while_option b c (c s) else Some s)" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 22 | proof cases | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 23 | assume "b s" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 24 | show ?thesis | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 25 | proof (cases "\<exists>k. ~ b ((c ^^ k) s)") | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 26 | case True | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 27 | then obtain k where 1: "~ b ((c ^^ k) s)" .. | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 28 | with `b s` obtain l where "k = Suc l" by (cases k) auto | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 29 | with 1 have "~ b ((c ^^ l) (c s))" by (auto simp: funpow_swap1) | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 30 | then have 2: "\<exists>l. ~ b ((c ^^ l) (c s))" .. | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 31 | from 1 | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 32 | have "(LEAST k. ~ b ((c ^^ k) s)) = Suc (LEAST l. ~ b ((c ^^ Suc l) s))" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 33 | by (rule Least_Suc) (simp add: `b s`) | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 34 | also have "... = Suc (LEAST l. ~ b ((c ^^ l) (c s)))" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 35 | by (simp add: funpow_swap1) | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 36 | finally | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 37 | show ?thesis | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 38 | using True 2 `b s` by (simp add: funpow_swap1 while_option_def) | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 39 | next | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 40 | case False | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 41 | then have "~ (\<exists>l. ~ b ((c ^^ Suc l) s))" by blast | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 42 | then have "~ (\<exists>l. ~ b ((c ^^ l) (c s)))" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 43 | by (simp add: funpow_swap1) | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 44 | with False `b s` show ?thesis by (simp add: while_option_def) | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 45 | qed | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 46 | next | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 47 | assume [simp]: "~ b s" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 48 | have least: "(LEAST k. ~ b ((c ^^ k) s)) = 0" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 49 | by (rule Least_equality) auto | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 50 | moreover | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 51 | have "\<exists>k. ~ b ((c ^^ k) s)" by (rule exI[of _ "0::nat"]) auto | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 52 | ultimately show ?thesis unfolding while_option_def by auto | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 53 | qed | 
| 10251 | 54 | |
| 37757 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 55 | lemma while_option_stop: | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 56 | assumes "while_option b c s = Some t" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 57 | shows "~ b t" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 58 | proof - | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 59 | from assms have ex: "\<exists>k. ~ b ((c ^^ k) s)" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 60 | and t: "t = (c ^^ (LEAST k. ~ b ((c ^^ k) s))) s" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 61 | by (auto simp: while_option_def split: if_splits) | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 62 | from LeastI_ex[OF ex] | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 63 | show "~ b t" unfolding t . | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 64 | qed | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 65 | |
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 66 | theorem while_option_rule: | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 67 | assumes step: "!!s. P s ==> b s ==> P (c s)" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 68 | and result: "while_option b c s = Some t" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 69 | and init: "P s" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 70 | shows "P t" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 71 | proof - | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 72 | def k == "LEAST k. ~ b ((c ^^ k) s)" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 73 | from assms have t: "t = (c ^^ k) s" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 74 | by (simp add: while_option_def k_def split: if_splits) | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 75 | have 1: "ALL i<k. b ((c ^^ i) s)" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 76 | by (auto simp: k_def dest: not_less_Least) | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 77 | |
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 78 |   { fix i assume "i <= k" then have "P ((c ^^ i) s)"
 | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 79 | by (induct i) (auto simp: init step 1) } | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 80 | thus "P t" by (auto simp: t) | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 81 | qed | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 82 | |
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 83 | |
| 37760 | 84 | subsection {* Total version *}
 | 
| 37757 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 85 | |
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 86 | definition while :: "('a \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> 'a \<Rightarrow> 'a"
 | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 87 | where "while b c s = the (while_option b c s)" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 88 | |
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 89 | lemma while_unfold: | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 90 | "while b c s = (if b s then while b c (c s) else s)" | 
| 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 91 | unfolding while_def by (subst while_option_unfold) simp | 
| 10984 | 92 | |
| 18372 | 93 | lemma def_while_unfold: | 
| 94 | assumes fdef: "f == while test do" | |
| 95 | shows "f x = (if test x then f(do x) else x)" | |
| 37757 
dc78d2d9e90a
added "while_option", which needs no well-foundedness; defined "while" in terms of "while_option"
 krauss parents: 
30738diff
changeset | 96 | unfolding fdef by (fact while_unfold) | 
| 14300 | 97 | |
| 98 | ||
| 10251 | 99 | text {*
 | 
| 100 |  The proof rule for @{term while}, where @{term P} is the invariant.
 | |
| 101 | *} | |
| 102 | ||
| 18372 | 103 | theorem while_rule_lemma: | 
| 104 | assumes invariant: "!!s. P s ==> b s ==> P (c s)" | |
| 105 | and terminate: "!!s. P s ==> \<not> b s ==> Q s" | |
| 106 |     and wf: "wf {(t, s). P s \<and> b s \<and> t = c s}"
 | |
| 107 | shows "P s \<Longrightarrow> Q (while b c s)" | |
| 19736 | 108 | using wf | 
| 109 | apply (induct s) | |
| 18372 | 110 | apply simp | 
| 111 | apply (subst while_unfold) | |
| 112 | apply (simp add: invariant terminate) | |
| 113 | done | |
| 10251 | 114 | |
| 10653 | 115 | theorem while_rule: | 
| 10984 | 116 | "[| P s; | 
| 117 | !!s. [| P s; b s |] ==> P (c s); | |
| 118 | !!s. [| P s; \<not> b s |] ==> Q s; | |
| 10997 | 119 | wf r; | 
| 10984 | 120 | !!s. [| P s; b s |] ==> (c s, s) \<in> r |] ==> | 
| 121 | Q (while b c s)" | |
| 19736 | 122 | apply (rule while_rule_lemma) | 
| 123 | prefer 4 apply assumption | |
| 124 | apply blast | |
| 125 | apply blast | |
| 126 | apply (erule wf_subset) | |
| 127 | apply blast | |
| 128 | done | |
| 10653 | 129 | |
| 41720 | 130 | text{* Proving termination: *}
 | 
| 131 | ||
| 132 | theorem wf_while_option_Some: | |
| 41764 | 133 |   assumes "wf {(t, s). (P s \<and> b s) \<and> t = c s}"
 | 
| 134 | and "!!s. P s \<Longrightarrow> b s \<Longrightarrow> P(c s)" and "P s" | |
| 41720 | 135 | shows "EX t. while_option b c s = Some t" | 
| 41764 | 136 | using assms(1,3) | 
| 41720 | 137 | apply (induct s) | 
| 41764 | 138 | using assms(2) | 
| 41720 | 139 | apply (subst while_option_unfold) | 
| 140 | apply simp | |
| 141 | done | |
| 142 | ||
| 143 | theorem measure_while_option_Some: fixes f :: "'s \<Rightarrow> nat" | |
| 41764 | 144 | shows "(!!s. P s \<Longrightarrow> b s \<Longrightarrow> P(c s) \<and> f(c s) < f s) | 
| 145 | \<Longrightarrow> P s \<Longrightarrow> EX t. while_option b c s = Some t" | |
| 146 | by(blast intro: wf_while_option_Some[OF wf_if_measure, of P b f]) | |
| 10251 | 147 | |
| 148 | end |