| author | paulson <lp15@cam.ac.uk> | 
| Sun, 03 Apr 2022 14:48:55 +0100 | |
| changeset 75400 | 970b9ab6c439 | 
| parent 69587 | 53982d5ec0bb | 
| child 76213 | e44d86131648 | 
| permissions | -rw-r--r-- | 
| 37936 | 1 | (* Title: ZF/UNITY/WFair.thy | 
| 11479 | 2 | Author: Sidi Ehmety, Computer Laboratory | 
| 3 | Copyright 1998 University of Cambridge | |
| 4 | *) | |
| 5 | ||
| 60770 | 6 | section\<open>Progress under Weak Fairness\<close> | 
| 15634 | 7 | |
| 8 | theory WFair | |
| 65449 
c82e63b11b8b
clarified main ZF.thy / ZFC.thy, and avoid name clash with global HOL/Main.thy;
 wenzelm parents: 
61798diff
changeset | 9 | imports UNITY ZFC | 
| 15634 | 10 | begin | 
| 11 | ||
| 60770 | 12 | text\<open>This theory defines the operators transient, ensures and leadsTo, | 
| 15634 | 13 | assuming weak fairness. From Misra, "A Logic for Concurrent Programming", | 
| 60770 | 14 | 1994.\<close> | 
| 15634 | 15 | |
| 24893 | 16 | definition | 
| 12195 | 17 | (* This definition specifies weak fairness. The rest of the theory | 
| 46953 | 18 | is generic to all forms of fairness.*) | 
| 24893 | 19 | transient :: "i=>i" where | 
| 46953 | 20 |   "transient(A) =={F \<in> program. (\<exists>act\<in>Acts(F). A<=domain(act) &
 | 
| 46823 | 21 | act``A \<subseteq> state-A) & st_set(A)}" | 
| 11479 | 22 | |
| 24893 | 23 | definition | 
| 69587 | 24 | ensures :: "[i,i] => i" (infixl \<open>ensures\<close> 60) where | 
| 46823 | 25 | "A ensures B == ((A-B) co (A \<union> B)) \<inter> transient(A-B)" | 
| 46953 | 26 | |
| 11479 | 27 | consts | 
| 28 | ||
| 29 | (*LEADS-TO constant for the inductive definition*) | |
| 12195 | 30 | leads :: "[i, i]=>i" | 
| 11479 | 31 | |
| 46953 | 32 | inductive | 
| 11479 | 33 | domains | 
| 46823 | 34 | "leads(D, F)" \<subseteq> "Pow(D)*Pow(D)" | 
| 46953 | 35 | intros | 
| 36 | Basis: "[| F \<in> A ensures B; A \<in> Pow(D); B \<in> Pow(D) |] ==> <A,B>:leads(D, F)" | |
| 46823 | 37 | Trans: "[| <A,B> \<in> leads(D, F); <B,C> \<in> leads(D, F) |] ==> <A,C>:leads(D, F)" | 
| 46953 | 38 |     Union:   "[| S \<in> Pow({A \<in> S. <A, B>:leads(D, F)}); B \<in> Pow(D); S \<in> Pow(Pow(D)) |] ==>
 | 
| 46823 | 39 | <\<Union>(S),B>:leads(D, F)" | 
| 11479 | 40 | |
| 41 | monos Pow_mono | |
| 15634 | 42 | type_intros Union_Pow_iff [THEN iffD2] UnionI PowI | 
| 46953 | 43 | |
| 24893 | 44 | definition | 
| 12195 | 45 | (* The Visible version of the LEADS-TO relation*) | 
| 69587 | 46 | leadsTo :: "[i, i] => i" (infixl \<open>\<longmapsto>\<close> 60) where | 
| 61392 | 47 |   "A \<longmapsto> B == {F \<in> program. <A,B>:leads(state, F)}"
 | 
| 46953 | 48 | |
| 24893 | 49 | definition | 
| 12195 | 50 | (* wlt(F, B) is the largest set that leads to B*) | 
| 24893 | 51 | wlt :: "[i, i] => i" where | 
| 61392 | 52 |     "wlt(F, B) == \<Union>({A \<in> Pow(state). F \<in> A \<longmapsto> B})"
 | 
| 15634 | 53 | |
| 54 | (** Ad-hoc set-theory rules **) | |
| 55 | ||
| 46823 | 56 | lemma Int_Union_Union: "\<Union>(B) \<inter> A = (\<Union>b \<in> B. b \<inter> A)" | 
| 15634 | 57 | by auto | 
| 58 | ||
| 46823 | 59 | lemma Int_Union_Union2: "A \<inter> \<Union>(B) = (\<Union>b \<in> B. A \<inter> b)" | 
| 15634 | 60 | by auto | 
| 61 | ||
| 62 | (*** transient ***) | |
| 63 | ||
| 64 | lemma transient_type: "transient(A)<=program" | |
| 65 | by (unfold transient_def, auto) | |
| 66 | ||
| 46953 | 67 | lemma transientD2: | 
| 15634 | 68 | "F \<in> transient(A) ==> F \<in> program & st_set(A)" | 
| 69 | apply (unfold transient_def, auto) | |
| 70 | done | |
| 71 | ||
| 72 | lemma stable_transient_empty: "[| F \<in> stable(A); F \<in> transient(A) |] ==> A = 0" | |
| 73 | by (simp add: stable_def constrains_def transient_def, fast) | |
| 74 | ||
| 75 | lemma transient_strengthen: "[|F \<in> transient(A); B<=A|] ==> F \<in> transient(B)" | |
| 76 | apply (simp add: transient_def st_set_def, clarify) | |
| 77 | apply (blast intro!: rev_bexI) | |
| 78 | done | |
| 79 | ||
| 46953 | 80 | lemma transientI: | 
| 81 | "[|act \<in> Acts(F); A \<subseteq> domain(act); act``A \<subseteq> state-A; | |
| 15634 | 82 | F \<in> program; st_set(A)|] ==> F \<in> transient(A)" | 
| 83 | by (simp add: transient_def, blast) | |
| 84 | ||
| 46953 | 85 | lemma transientE: | 
| 86 | "[| F \<in> transient(A); | |
| 46823 | 87 | !!act. [| act \<in> Acts(F); A \<subseteq> domain(act); act``A \<subseteq> state-A|]==>P|] | 
| 15634 | 88 | ==>P" | 
| 89 | by (simp add: transient_def, blast) | |
| 90 | ||
| 91 | lemma transient_state: "transient(state) = 0" | |
| 92 | apply (simp add: transient_def) | |
| 46953 | 93 | apply (rule equalityI, auto) | 
| 15634 | 94 | apply (cut_tac F = x in Acts_type) | 
| 95 | apply (simp add: Diff_cancel) | |
| 96 | apply (auto intro: st0_in_state) | |
| 97 | done | |
| 98 | ||
| 99 | lemma transient_state2: "state<=B ==> transient(B) = 0" | |
| 100 | apply (simp add: transient_def st_set_def) | |
| 101 | apply (rule equalityI, auto) | |
| 102 | apply (cut_tac F = x in Acts_type) | |
| 103 | apply (subgoal_tac "B=state") | |
| 104 | apply (auto intro: st0_in_state) | |
| 105 | done | |
| 106 | ||
| 107 | lemma transient_empty: "transient(0) = program" | |
| 108 | by (auto simp add: transient_def) | |
| 109 | ||
| 110 | declare transient_empty [simp] transient_state [simp] transient_state2 [simp] | |
| 111 | ||
| 112 | (*** ensures ***) | |
| 113 | ||
| 114 | lemma ensures_type: "A ensures B <=program" | |
| 115 | by (simp add: ensures_def constrains_def, auto) | |
| 116 | ||
| 46953 | 117 | lemma ensuresI: | 
| 46823 | 118 | "[|F:(A-B) co (A \<union> B); F \<in> transient(A-B)|]==>F \<in> A ensures B" | 
| 15634 | 119 | apply (unfold ensures_def) | 
| 120 | apply (auto simp add: transient_type [THEN subsetD]) | |
| 121 | done | |
| 122 | ||
| 123 | (* Added by Sidi, from Misra's notes, Progress chapter, exercise 4 *) | |
| 46823 | 124 | lemma ensuresI2: "[| F \<in> A co A \<union> B; F \<in> transient(A) |] ==> F \<in> A ensures B" | 
| 15634 | 125 | apply (drule_tac B = "A-B" in constrains_weaken_L) | 
| 126 | apply (drule_tac [2] B = "A-B" in transient_strengthen) | |
| 127 | apply (auto simp add: ensures_def transient_type [THEN subsetD]) | |
| 128 | done | |
| 129 | ||
| 46823 | 130 | lemma ensuresD: "F \<in> A ensures B ==> F:(A-B) co (A \<union> B) & F \<in> transient (A-B)" | 
| 15634 | 131 | by (unfold ensures_def, auto) | 
| 132 | ||
| 133 | lemma ensures_weaken_R: "[|F \<in> A ensures A'; A'<=B' |] ==> F \<in> A ensures B'" | |
| 134 | apply (unfold ensures_def) | |
| 135 | apply (blast intro: transient_strengthen constrains_weaken) | |
| 136 | done | |
| 137 | ||
| 46953 | 138 | (*The L-version (precondition strengthening) fails, but we have this*) | 
| 139 | lemma stable_ensures_Int: | |
| 46823 | 140 | "[| F \<in> stable(C); F \<in> A ensures B |] ==> F:(C \<inter> A) ensures (C \<inter> B)" | 
| 46953 | 141 | |
| 15634 | 142 | apply (unfold ensures_def) | 
| 143 | apply (simp (no_asm) add: Int_Un_distrib [symmetric] Diff_Int_distrib [symmetric]) | |
| 144 | apply (blast intro: transient_strengthen stable_constrains_Int constrains_weaken) | |
| 145 | done | |
| 146 | ||
| 46823 | 147 | lemma stable_transient_ensures: "[|F \<in> stable(A); F \<in> transient(C); A<=B \<union> C|] ==> F \<in> A ensures B" | 
| 15634 | 148 | apply (frule stable_type [THEN subsetD]) | 
| 149 | apply (simp add: ensures_def stable_def) | |
| 150 | apply (blast intro: transient_strengthen constrains_weaken) | |
| 151 | done | |
| 152 | ||
| 46823 | 153 | lemma ensures_eq: "(A ensures B) = (A unless B) \<inter> transient (A-B)" | 
| 15634 | 154 | by (auto simp add: ensures_def unless_def) | 
| 155 | ||
| 156 | lemma subset_imp_ensures: "[| F \<in> program; A<=B |] ==> F \<in> A ensures B" | |
| 157 | by (auto simp add: ensures_def constrains_def transient_def st_set_def) | |
| 158 | ||
| 159 | (*** leadsTo ***) | |
| 160 | lemmas leads_left = leads.dom_subset [THEN subsetD, THEN SigmaD1] | |
| 161 | lemmas leads_right = leads.dom_subset [THEN subsetD, THEN SigmaD2] | |
| 162 | ||
| 61392 | 163 | lemma leadsTo_type: "A \<longmapsto> B \<subseteq> program" | 
| 15634 | 164 | by (unfold leadsTo_def, auto) | 
| 165 | ||
| 46953 | 166 | lemma leadsToD2: | 
| 61392 | 167 | "F \<in> A \<longmapsto> B ==> F \<in> program & st_set(A) & st_set(B)" | 
| 15634 | 168 | apply (unfold leadsTo_def st_set_def) | 
| 169 | apply (blast dest: leads_left leads_right) | |
| 170 | done | |
| 171 | ||
| 46953 | 172 | lemma leadsTo_Basis: | 
| 61392 | 173 | "[|F \<in> A ensures B; st_set(A); st_set(B)|] ==> F \<in> A \<longmapsto> B" | 
| 15634 | 174 | apply (unfold leadsTo_def st_set_def) | 
| 175 | apply (cut_tac ensures_type) | |
| 176 | apply (auto intro: leads.Basis) | |
| 177 | done | |
| 178 | declare leadsTo_Basis [intro] | |
| 179 | ||
| 180 | (* Added by Sidi, from Misra's notes, Progress chapter, exercise number 4 *) | |
| 61392 | 181 | (* [| F \<in> program; A<=B; st_set(A); st_set(B) |] ==> A \<longmapsto> B *) | 
| 45602 | 182 | lemmas subset_imp_leadsTo = subset_imp_ensures [THEN leadsTo_Basis] | 
| 15634 | 183 | |
| 61392 | 184 | lemma leadsTo_Trans: "[|F \<in> A \<longmapsto> B; F \<in> B \<longmapsto> C |]==>F \<in> A \<longmapsto> C" | 
| 15634 | 185 | apply (unfold leadsTo_def) | 
| 186 | apply (auto intro: leads.Trans) | |
| 187 | done | |
| 188 | ||
| 189 | (* Better when used in association with leadsTo_weaken_R *) | |
| 61392 | 190 | lemma transient_imp_leadsTo: "F \<in> transient(A) ==> F \<in> A \<longmapsto> (state-A)" | 
| 15634 | 191 | apply (unfold transient_def) | 
| 192 | apply (blast intro: ensuresI [THEN leadsTo_Basis] constrains_weaken transientI) | |
| 193 | done | |
| 194 | ||
| 195 | (*Useful with cancellation, disjunction*) | |
| 61392 | 196 | lemma leadsTo_Un_duplicate: "F \<in> A \<longmapsto> (A' \<union> A') ==> F \<in> A \<longmapsto> A'" | 
| 15634 | 197 | by simp | 
| 198 | ||
| 199 | lemma leadsTo_Un_duplicate2: | |
| 61392 | 200 | "F \<in> A \<longmapsto> (A' \<union> C \<union> C) ==> F \<in> A \<longmapsto> (A' \<union> C)" | 
| 15634 | 201 | by (simp add: Un_ac) | 
| 202 | ||
| 203 | (*The Union introduction rule as we should have liked to state it*) | |
| 46953 | 204 | lemma leadsTo_Union: | 
| 61392 | 205 | "[|!!A. A \<in> S ==> F \<in> A \<longmapsto> B; F \<in> program; st_set(B)|] | 
| 206 | ==> F \<in> \<Union>(S) \<longmapsto> B" | |
| 15634 | 207 | apply (unfold leadsTo_def st_set_def) | 
| 208 | apply (blast intro: leads.Union dest: leads_left) | |
| 209 | done | |
| 210 | ||
| 46953 | 211 | lemma leadsTo_Union_Int: | 
| 61392 | 212 | "[|!!A. A \<in> S ==>F \<in> (A \<inter> C) \<longmapsto> B; F \<in> program; st_set(B)|] | 
| 213 | ==> F \<in> (\<Union>(S)Int C)\<longmapsto> B" | |
| 15634 | 214 | apply (unfold leadsTo_def st_set_def) | 
| 215 | apply (simp only: Int_Union_Union) | |
| 216 | apply (blast dest: leads_left intro: leads.Union) | |
| 217 | done | |
| 218 | ||
| 46953 | 219 | lemma leadsTo_UN: | 
| 61392 | 220 | "[| !!i. i \<in> I ==> F \<in> A(i) \<longmapsto> B; F \<in> program; st_set(B)|] | 
| 221 | ==> F:(\<Union>i \<in> I. A(i)) \<longmapsto> B" | |
| 15634 | 222 | apply (simp add: Int_Union_Union leadsTo_def st_set_def) | 
| 223 | apply (blast dest: leads_left intro: leads.Union) | |
| 224 | done | |
| 225 | ||
| 226 | (* Binary union introduction rule *) | |
| 227 | lemma leadsTo_Un: | |
| 61392 | 228 | "[| F \<in> A \<longmapsto> C; F \<in> B \<longmapsto> C |] ==> F \<in> (A \<union> B) \<longmapsto> C" | 
| 15634 | 229 | apply (subst Un_eq_Union) | 
| 230 | apply (blast intro: leadsTo_Union dest: leadsToD2) | |
| 231 | done | |
| 232 | ||
| 233 | lemma single_leadsTo_I: | |
| 61392 | 234 |     "[|!!x. x \<in> A==> F:{x} \<longmapsto> B; F \<in> program; st_set(B) |]
 | 
| 235 | ==> F \<in> A \<longmapsto> B" | |
| 15634 | 236 | apply (rule_tac b = A in UN_singleton [THEN subst]) | 
| 46953 | 237 | apply (rule leadsTo_UN, auto) | 
| 15634 | 238 | done | 
| 239 | ||
| 61392 | 240 | lemma leadsTo_refl: "[| F \<in> program; st_set(A) |] ==> F \<in> A \<longmapsto> A" | 
| 15634 | 241 | by (blast intro: subset_imp_leadsTo) | 
| 242 | ||
| 61392 | 243 | lemma leadsTo_refl_iff: "F \<in> A \<longmapsto> A \<longleftrightarrow> F \<in> program & st_set(A)" | 
| 15634 | 244 | by (auto intro: leadsTo_refl dest: leadsToD2) | 
| 245 | ||
| 61392 | 246 | lemma empty_leadsTo: "F \<in> 0 \<longmapsto> B \<longleftrightarrow> (F \<in> program & st_set(B))" | 
| 15634 | 247 | by (auto intro: subset_imp_leadsTo dest: leadsToD2) | 
| 248 | declare empty_leadsTo [iff] | |
| 249 | ||
| 61392 | 250 | lemma leadsTo_state: "F \<in> A \<longmapsto> state \<longleftrightarrow> (F \<in> program & st_set(A))" | 
| 15634 | 251 | by (auto intro: subset_imp_leadsTo dest: leadsToD2 st_setD) | 
| 252 | declare leadsTo_state [iff] | |
| 253 | ||
| 61392 | 254 | lemma leadsTo_weaken_R: "[| F \<in> A \<longmapsto> A'; A'<=B'; st_set(B') |] ==> F \<in> A \<longmapsto> B'" | 
| 15634 | 255 | by (blast dest: leadsToD2 intro: subset_imp_leadsTo leadsTo_Trans) | 
| 256 | ||
| 61392 | 257 | lemma leadsTo_weaken_L: "[| F \<in> A \<longmapsto> A'; B<=A |] ==> F \<in> B \<longmapsto> A'" | 
| 15634 | 258 | apply (frule leadsToD2) | 
| 259 | apply (blast intro: leadsTo_Trans subset_imp_leadsTo st_set_subset) | |
| 260 | done | |
| 261 | ||
| 61392 | 262 | lemma leadsTo_weaken: "[| F \<in> A \<longmapsto> A'; B<=A; A'<=B'; st_set(B')|]==> F \<in> B \<longmapsto> B'" | 
| 15634 | 263 | apply (frule leadsToD2) | 
| 264 | apply (blast intro: leadsTo_weaken_R leadsTo_weaken_L leadsTo_Trans leadsTo_refl) | |
| 265 | done | |
| 266 | ||
| 267 | (* This rule has a nicer conclusion *) | |
| 61392 | 268 | lemma transient_imp_leadsTo2: "[| F \<in> transient(A); state-A<=B; st_set(B)|] ==> F \<in> A \<longmapsto> B" | 
| 15634 | 269 | apply (frule transientD2) | 
| 270 | apply (rule leadsTo_weaken_R) | |
| 271 | apply (auto simp add: transient_imp_leadsTo) | |
| 272 | done | |
| 273 | ||
| 274 | (*Distributes over binary unions*) | |
| 61392 | 275 | lemma leadsTo_Un_distrib: "F:(A \<union> B) \<longmapsto> C \<longleftrightarrow> (F \<in> A \<longmapsto> C & F \<in> B \<longmapsto> C)" | 
| 15634 | 276 | by (blast intro: leadsTo_Un leadsTo_weaken_L) | 
| 277 | ||
| 46953 | 278 | lemma leadsTo_UN_distrib: | 
| 61392 | 279 | "(F:(\<Union>i \<in> I. A(i)) \<longmapsto> B)\<longleftrightarrow> ((\<forall>i \<in> I. F \<in> A(i) \<longmapsto> B) & F \<in> program & st_set(B))" | 
| 15634 | 280 | apply (blast dest: leadsToD2 intro: leadsTo_UN leadsTo_weaken_L) | 
| 281 | done | |
| 282 | ||
| 61392 | 283 | lemma leadsTo_Union_distrib: "(F \<in> \<Union>(S) \<longmapsto> B) \<longleftrightarrow> (\<forall>A \<in> S. F \<in> A \<longmapsto> B) & F \<in> program & st_set(B)" | 
| 15634 | 284 | by (blast dest: leadsToD2 intro: leadsTo_Union leadsTo_weaken_L) | 
| 285 | ||
| 61798 | 286 | text\<open>Set difference: maybe combine with \<open>leadsTo_weaken_L\<close>??\<close> | 
| 15634 | 287 | lemma leadsTo_Diff: | 
| 61392 | 288 | "[| F: (A-B) \<longmapsto> C; F \<in> B \<longmapsto> C; st_set(C) |] | 
| 289 | ==> F \<in> A \<longmapsto> C" | |
| 15634 | 290 | by (blast intro: leadsTo_Un leadsTo_weaken dest: leadsToD2) | 
| 291 | ||
| 292 | lemma leadsTo_UN_UN: | |
| 61392 | 293 | "[|!!i. i \<in> I ==> F \<in> A(i) \<longmapsto> A'(i); F \<in> program |] | 
| 294 | ==> F: (\<Union>i \<in> I. A(i)) \<longmapsto> (\<Union>i \<in> I. A'(i))" | |
| 15634 | 295 | apply (rule leadsTo_Union) | 
| 46953 | 296 | apply (auto intro: leadsTo_weaken_R dest: leadsToD2) | 
| 15634 | 297 | done | 
| 298 | ||
| 299 | (*Binary union version*) | |
| 61392 | 300 | lemma leadsTo_Un_Un: "[| F \<in> A \<longmapsto> A'; F \<in> B \<longmapsto> B' |] ==> F \<in> (A \<union> B) \<longmapsto> (A' \<union> B')" | 
| 15634 | 301 | apply (subgoal_tac "st_set (A) & st_set (A') & st_set (B) & st_set (B') ") | 
| 302 | prefer 2 apply (blast dest: leadsToD2) | |
| 303 | apply (blast intro: leadsTo_Un leadsTo_weaken_R) | |
| 304 | done | |
| 305 | ||
| 306 | (** The cancellation law **) | |
| 61392 | 307 | lemma leadsTo_cancel2: "[|F \<in> A \<longmapsto> (A' \<union> B); F \<in> B \<longmapsto> B'|] ==> F \<in> A \<longmapsto> (A' \<union> B')" | 
| 15634 | 308 | apply (subgoal_tac "st_set (A) & st_set (A') & st_set (B) & st_set (B') &F \<in> program") | 
| 309 | prefer 2 apply (blast dest: leadsToD2) | |
| 310 | apply (blast intro: leadsTo_Trans leadsTo_Un_Un leadsTo_refl) | |
| 311 | done | |
| 312 | ||
| 61392 | 313 | lemma leadsTo_cancel_Diff2: "[|F \<in> A \<longmapsto> (A' \<union> B); F \<in> (B-A') \<longmapsto> B'|]==> F \<in> A \<longmapsto> (A' \<union> B')" | 
| 15634 | 314 | apply (rule leadsTo_cancel2) | 
| 315 | prefer 2 apply assumption | |
| 316 | apply (blast dest: leadsToD2 intro: leadsTo_weaken_R) | |
| 317 | done | |
| 318 | ||
| 319 | ||
| 61392 | 320 | lemma leadsTo_cancel1: "[| F \<in> A \<longmapsto> (B \<union> A'); F \<in> B \<longmapsto> B' |] ==> F \<in> A \<longmapsto> (B' \<union> A')" | 
| 15634 | 321 | apply (simp add: Un_commute) | 
| 322 | apply (blast intro!: leadsTo_cancel2) | |
| 323 | done | |
| 324 | ||
| 325 | lemma leadsTo_cancel_Diff1: | |
| 61392 | 326 | "[|F \<in> A \<longmapsto> (B \<union> A'); F: (B-A') \<longmapsto> B'|]==> F \<in> A \<longmapsto> (B' \<union> A')" | 
| 15634 | 327 | apply (rule leadsTo_cancel1) | 
| 328 | prefer 2 apply assumption | |
| 329 | apply (blast intro: leadsTo_weaken_R dest: leadsToD2) | |
| 330 | done | |
| 331 | ||
| 332 | (*The INDUCTION rule as we should have liked to state it*) | |
| 333 | lemma leadsTo_induct: | |
| 61392 | 334 | assumes major: "F \<in> za \<longmapsto> zb" | 
| 15634 | 335 | and basis: "!!A B. [|F \<in> A ensures B; st_set(A); st_set(B)|] ==> P(A,B)" | 
| 61392 | 336 | and trans: "!!A B C. [| F \<in> A \<longmapsto> B; P(A, B); | 
| 337 | F \<in> B \<longmapsto> C; P(B, C) |] ==> P(A,C)" | |
| 338 | and union: "!!B S. [| \<forall>A \<in> S. F \<in> A \<longmapsto> B; \<forall>A \<in> S. P(A,B); | |
| 46823 | 339 | st_set(B); \<forall>A \<in> S. st_set(A)|] ==> P(\<Union>(S), B)" | 
| 15634 | 340 | shows "P(za, zb)" | 
| 341 | apply (cut_tac major) | |
| 46953 | 342 | apply (unfold leadsTo_def, clarify) | 
| 343 | apply (erule leads.induct) | |
| 15634 | 344 | apply (blast intro: basis [unfolded st_set_def]) | 
| 46953 | 345 | apply (blast intro: trans [unfolded leadsTo_def]) | 
| 346 | apply (force intro: union [unfolded st_set_def leadsTo_def]) | |
| 15634 | 347 | done | 
| 348 | ||
| 349 | ||
| 350 | (* Added by Sidi, an induction rule without ensures *) | |
| 351 | lemma leadsTo_induct2: | |
| 61392 | 352 | assumes major: "F \<in> za \<longmapsto> zb" | 
| 15634 | 353 | and basis1: "!!A B. [| A<=B; st_set(B) |] ==> P(A, B)" | 
| 46953 | 354 | and basis2: "!!A B. [| F \<in> A co A \<union> B; F \<in> transient(A); st_set(B) |] | 
| 15634 | 355 | ==> P(A, B)" | 
| 61392 | 356 | and trans: "!!A B C. [| F \<in> A \<longmapsto> B; P(A, B); | 
| 357 | F \<in> B \<longmapsto> C; P(B, C) |] ==> P(A,C)" | |
| 358 | and union: "!!B S. [| \<forall>A \<in> S. F \<in> A \<longmapsto> B; \<forall>A \<in> S. P(A,B); | |
| 46823 | 359 | st_set(B); \<forall>A \<in> S. st_set(A)|] ==> P(\<Union>(S), B)" | 
| 15634 | 360 | shows "P(za, zb)" | 
| 361 | apply (cut_tac major) | |
| 362 | apply (erule leadsTo_induct) | |
| 363 | apply (auto intro: trans union) | |
| 364 | apply (simp add: ensures_def, clarify) | |
| 365 | apply (frule constrainsD2) | |
| 46823 | 366 | apply (drule_tac B' = " (A-B) \<union> B" in constrains_weaken_R) | 
| 15634 | 367 | apply blast | 
| 368 | apply (frule ensuresI2 [THEN leadsTo_Basis]) | |
| 369 | apply (drule_tac [4] basis2, simp_all) | |
| 370 | apply (frule_tac A1 = A and B = B in Int_lower2 [THEN basis1]) | |
| 46823 | 371 | apply (subgoal_tac "A=\<Union>({A - B, A \<inter> B}) ")
 | 
| 15634 | 372 | prefer 2 apply blast | 
| 373 | apply (erule ssubst) | |
| 374 | apply (rule union) | |
| 375 | apply (auto intro: subset_imp_leadsTo) | |
| 376 | done | |
| 377 | ||
| 378 | ||
| 379 | (** Variant induction rule: on the preconditions for B **) | |
| 380 | (*Lemma is the weak version: can't see how to do it in one step*) | |
| 46953 | 381 | lemma leadsTo_induct_pre_aux: | 
| 61392 | 382 | "[| F \<in> za \<longmapsto> zb; | 
| 46953 | 383 | P(zb); | 
| 384 | !!A B. [| F \<in> A ensures B; P(B); st_set(A); st_set(B) |] ==> P(A); | |
| 385 | !!S. [| \<forall>A \<in> S. P(A); \<forall>A \<in> S. st_set(A) |] ==> P(\<Union>(S)) | |
| 15634 | 386 | |] ==> P(za)" | 
| 60770 | 387 | txt\<open>by induction on this formula\<close> | 
| 46823 | 388 | apply (subgoal_tac "P (zb) \<longrightarrow> P (za) ") | 
| 60770 | 389 | txt\<open>now solve first subgoal: this formula is sufficient\<close> | 
| 15634 | 390 | apply (blast intro: leadsTo_refl) | 
| 391 | apply (erule leadsTo_induct) | |
| 392 | apply (blast+) | |
| 393 | done | |
| 394 | ||
| 395 | ||
| 46953 | 396 | lemma leadsTo_induct_pre: | 
| 61392 | 397 | "[| F \<in> za \<longmapsto> zb; | 
| 46953 | 398 | P(zb); | 
| 61392 | 399 | !!A B. [| F \<in> A ensures B; F \<in> B \<longmapsto> zb; P(B); st_set(A) |] ==> P(A); | 
| 400 | !!S. \<forall>A \<in> S. F \<in> A \<longmapsto> zb & P(A) & st_set(A) ==> P(\<Union>(S)) | |
| 15634 | 401 | |] ==> P(za)" | 
| 61392 | 402 | apply (subgoal_tac " (F \<in> za \<longmapsto> zb) & P (za) ") | 
| 15634 | 403 | apply (erule conjunct2) | 
| 46953 | 404 | apply (frule leadsToD2) | 
| 15634 | 405 | apply (erule leadsTo_induct_pre_aux) | 
| 406 | prefer 3 apply (blast dest: leadsToD2 intro: leadsTo_Union) | |
| 407 | prefer 2 apply (blast intro: leadsTo_Trans leadsTo_Basis) | |
| 408 | apply (blast intro: leadsTo_refl) | |
| 409 | done | |
| 410 | ||
| 411 | (** The impossibility law **) | |
| 46953 | 412 | lemma leadsTo_empty: | 
| 61392 | 413 | "F \<in> A \<longmapsto> 0 ==> A=0" | 
| 15634 | 414 | apply (erule leadsTo_induct_pre) | 
| 415 | apply (auto simp add: ensures_def constrains_def transient_def st_set_def) | |
| 416 | apply (drule bspec, assumption)+ | |
| 417 | apply blast | |
| 418 | done | |
| 419 | declare leadsTo_empty [simp] | |
| 420 | ||
| 60770 | 421 | subsection\<open>PSP: Progress-Safety-Progress\<close> | 
| 15634 | 422 | |
| 60770 | 423 | text\<open>Special case of PSP: Misra's "stable conjunction"\<close> | 
| 15634 | 424 | |
| 46953 | 425 | lemma psp_stable: | 
| 61392 | 426 | "[| F \<in> A \<longmapsto> A'; F \<in> stable(B) |] ==> F:(A \<inter> B) \<longmapsto> (A' \<inter> B)" | 
| 15634 | 427 | apply (unfold stable_def) | 
| 46953 | 428 | apply (frule leadsToD2) | 
| 15634 | 429 | apply (erule leadsTo_induct) | 
| 430 | prefer 3 apply (blast intro: leadsTo_Union_Int) | |
| 431 | prefer 2 apply (blast intro: leadsTo_Trans) | |
| 432 | apply (rule leadsTo_Basis) | |
| 433 | apply (simp add: ensures_def Diff_Int_distrib2 [symmetric] Int_Un_distrib2 [symmetric]) | |
| 434 | apply (auto intro: transient_strengthen constrains_Int) | |
| 435 | done | |
| 436 | ||
| 437 | ||
| 61392 | 438 | lemma psp_stable2: "[|F \<in> A \<longmapsto> A'; F \<in> stable(B) |]==>F: (B \<inter> A) \<longmapsto> (B \<inter> A')" | 
| 15634 | 439 | apply (simp (no_asm_simp) add: psp_stable Int_ac) | 
| 440 | done | |
| 441 | ||
| 46953 | 442 | lemma psp_ensures: | 
| 46823 | 443 | "[| F \<in> A ensures A'; F \<in> B co B' |]==> F: (A \<inter> B') ensures ((A' \<inter> B) \<union> (B' - B))" | 
| 15634 | 444 | apply (unfold ensures_def constrains_def st_set_def) | 
| 445 | (*speeds up the proof*) | |
| 446 | apply clarify | |
| 447 | apply (blast intro: transient_strengthen) | |
| 448 | done | |
| 449 | ||
| 46953 | 450 | lemma psp: | 
| 61392 | 451 | "[|F \<in> A \<longmapsto> A'; F \<in> B co B'; st_set(B')|]==> F:(A \<inter> B') \<longmapsto> ((A' \<inter> B) \<union> (B' - B))" | 
| 15634 | 452 | apply (subgoal_tac "F \<in> program & st_set (A) & st_set (A') & st_set (B) ") | 
| 453 | prefer 2 apply (blast dest!: constrainsD2 leadsToD2) | |
| 454 | apply (erule leadsTo_induct) | |
| 455 | prefer 3 apply (blast intro: leadsTo_Union_Int) | |
| 60770 | 456 | txt\<open>Basis case\<close> | 
| 15634 | 457 | apply (blast intro: psp_ensures leadsTo_Basis) | 
| 60770 | 458 | txt\<open>Transitivity case has a delicate argument involving "cancellation"\<close> | 
| 15634 | 459 | apply (rule leadsTo_Un_duplicate2) | 
| 460 | apply (erule leadsTo_cancel_Diff1) | |
| 461 | apply (simp add: Int_Diff Diff_triv) | |
| 462 | apply (blast intro: leadsTo_weaken_L dest: constrains_imp_subset) | |
| 463 | done | |
| 464 | ||
| 465 | ||
| 61392 | 466 | lemma psp2: "[| F \<in> A \<longmapsto> A'; F \<in> B co B'; st_set(B') |] | 
| 467 | ==> F \<in> (B' \<inter> A) \<longmapsto> ((B \<inter> A') \<union> (B' - B))" | |
| 15634 | 468 | by (simp (no_asm_simp) add: psp Int_ac) | 
| 469 | ||
| 46953 | 470 | lemma psp_unless: | 
| 61392 | 471 | "[| F \<in> A \<longmapsto> A'; F \<in> B unless B'; st_set(B); st_set(B') |] | 
| 472 | ==> F \<in> (A \<inter> B) \<longmapsto> ((A' \<inter> B) \<union> B')" | |
| 15634 | 473 | apply (unfold unless_def) | 
| 474 | apply (subgoal_tac "st_set (A) &st_set (A') ") | |
| 475 | prefer 2 apply (blast dest: leadsToD2) | |
| 476 | apply (drule psp, assumption, blast) | |
| 477 | apply (blast intro: leadsTo_weaken) | |
| 478 | done | |
| 479 | ||
| 480 | ||
| 60770 | 481 | subsection\<open>Proving the induction rules\<close> | 
| 15634 | 482 | |
| 483 | (** The most general rule \<in> r is any wf relation; f is any variant function **) | |
| 46953 | 484 | lemma leadsTo_wf_induct_aux: "[| wf(r); | 
| 485 | m \<in> I; | |
| 486 | field(r)<=I; | |
| 487 | F \<in> program; st_set(B); | |
| 61392 | 488 |          \<forall>m \<in> I. F \<in> (A \<inter> f-``{m}) \<longmapsto>
 | 
| 46953 | 489 |                     ((A \<inter> f-``(converse(r)``{m})) \<union> B) |]
 | 
| 61392 | 490 |       ==> F \<in> (A \<inter> f-``{m}) \<longmapsto> B"
 | 
| 15634 | 491 | apply (erule_tac a = m in wf_induct2, simp_all) | 
| 61392 | 492 | apply (subgoal_tac "F \<in> (A \<inter> (f-`` (converse (r) ``{x}))) \<longmapsto> B")
 | 
| 15634 | 493 | apply (blast intro: leadsTo_cancel1 leadsTo_Un_duplicate) | 
| 494 | apply (subst vimage_eq_UN) | |
| 495 | apply (simp del: UN_simps add: Int_UN_distrib) | |
| 496 | apply (auto intro: leadsTo_UN simp del: UN_simps simp add: Int_UN_distrib) | |
| 497 | done | |
| 498 | ||
| 499 | (** Meta or object quantifier ? **) | |
| 46953 | 500 | lemma leadsTo_wf_induct: "[| wf(r); | 
| 501 | field(r)<=I; | |
| 502 | A<=f-``I; | |
| 503 | F \<in> program; st_set(A); st_set(B); | |
| 61392 | 504 |          \<forall>m \<in> I. F \<in> (A \<inter> f-``{m}) \<longmapsto>
 | 
| 46953 | 505 |                     ((A \<inter> f-``(converse(r)``{m})) \<union> B) |]
 | 
| 61392 | 506 | ==> F \<in> A \<longmapsto> B" | 
| 15634 | 507 | apply (rule_tac b = A in subst) | 
| 508 | defer 1 | |
| 509 | apply (rule_tac I = I in leadsTo_UN) | |
| 46953 | 510 | apply (erule_tac I = I in leadsTo_wf_induct_aux, assumption+, best) | 
| 15634 | 511 | done | 
| 512 | ||
| 513 | lemma nat_measure_field: "field(measure(nat, %x. x)) = nat" | |
| 514 | apply (unfold field_def) | |
| 515 | apply (simp add: measure_def) | |
| 516 | apply (rule equalityI, force, clarify) | |
| 59788 | 517 | apply (erule_tac V = "x\<notin>range (y)" for y in thin_rl) | 
| 15634 | 518 | apply (erule nat_induct) | 
| 519 | apply (rule_tac [2] b = "succ (succ (xa))" in domainI) | |
| 520 | apply (rule_tac b = "succ (0) " in domainI) | |
| 521 | apply simp_all | |
| 522 | done | |
| 523 | ||
| 524 | ||
| 525 | lemma Image_inverse_lessThan: "k<A ==> measure(A, %x. x) -`` {k} = k"
 | |
| 526 | apply (rule equalityI) | |
| 527 | apply (auto simp add: measure_def) | |
| 528 | apply (blast intro: ltD) | |
| 529 | apply (rule vimageI) | |
| 530 | prefer 2 apply blast | |
| 531 | apply (simp add: lt_Ord lt_Ord2 Ord_mem_iff_lt) | |
| 532 | apply (blast intro: lt_trans) | |
| 533 | done | |
| 534 | ||
| 61392 | 535 | (*Alternative proof is via the lemma F \<in> (A \<inter> f-`(lessThan m)) \<longmapsto> B*) | 
| 46953 | 536 | lemma lessThan_induct: | 
| 537 | "[| A<=f-``nat; | |
| 538 | F \<in> program; st_set(A); st_set(B); | |
| 61392 | 539 |      \<forall>m \<in> nat. F:(A \<inter> f-``{m}) \<longmapsto> ((A \<inter> f -`` m) \<union> B) |]
 | 
| 540 | ==> F \<in> A \<longmapsto> B" | |
| 46953 | 541 | apply (rule_tac A1 = nat and f1 = "%x. x" in wf_measure [THEN leadsTo_wf_induct]) | 
| 15634 | 542 | apply (simp_all add: nat_measure_field) | 
| 543 | apply (simp add: ltI Image_inverse_lessThan vimage_def [symmetric]) | |
| 544 | done | |
| 545 | ||
| 546 | ||
| 547 | (*** wlt ****) | |
| 548 | ||
| 549 | (*Misra's property W3*) | |
| 550 | lemma wlt_type: "wlt(F,B) <=state" | |
| 551 | by (unfold wlt_def, auto) | |
| 552 | ||
| 553 | lemma wlt_st_set: "st_set(wlt(F, B))" | |
| 554 | apply (unfold st_set_def) | |
| 555 | apply (rule wlt_type) | |
| 556 | done | |
| 557 | declare wlt_st_set [iff] | |
| 558 | ||
| 61392 | 559 | lemma wlt_leadsTo_iff: "F \<in> wlt(F, B) \<longmapsto> B \<longleftrightarrow> (F \<in> program & st_set(B))" | 
| 15634 | 560 | apply (unfold wlt_def) | 
| 561 | apply (blast dest: leadsToD2 intro!: leadsTo_Union) | |
| 562 | done | |
| 563 | ||
| 61392 | 564 | (* [| F \<in> program; st_set(B) |] ==> F \<in> wlt(F, B) \<longmapsto> B *) | 
| 45602 | 565 | lemmas wlt_leadsTo = conjI [THEN wlt_leadsTo_iff [THEN iffD2]] | 
| 15634 | 566 | |
| 61392 | 567 | lemma leadsTo_subset: "F \<in> A \<longmapsto> B ==> A \<subseteq> wlt(F, B)" | 
| 15634 | 568 | apply (unfold wlt_def) | 
| 569 | apply (frule leadsToD2) | |
| 570 | apply (auto simp add: st_set_def) | |
| 571 | done | |
| 572 | ||
| 573 | (*Misra's property W2*) | |
| 61392 | 574 | lemma leadsTo_eq_subset_wlt: "F \<in> A \<longmapsto> B \<longleftrightarrow> (A \<subseteq> wlt(F,B) & F \<in> program & st_set(B))" | 
| 15634 | 575 | apply auto | 
| 576 | apply (blast dest: leadsToD2 leadsTo_subset intro: leadsTo_weaken_L wlt_leadsTo)+ | |
| 577 | done | |
| 578 | ||
| 579 | (*Misra's property W4*) | |
| 46823 | 580 | lemma wlt_increasing: "[| F \<in> program; st_set(B) |] ==> B \<subseteq> wlt(F,B)" | 
| 15634 | 581 | apply (rule leadsTo_subset) | 
| 582 | apply (simp (no_asm_simp) add: leadsTo_eq_subset_wlt [THEN iff_sym] subset_imp_leadsTo) | |
| 583 | done | |
| 584 | ||
| 585 | (*Used in the Trans case below*) | |
| 46953 | 586 | lemma leadsTo_123_aux: | 
| 587 | "[| B \<subseteq> A2; | |
| 588 | F \<in> (A1 - B) co (A1 \<union> B); | |
| 589 | F \<in> (A2 - C) co (A2 \<union> C) |] | |
| 46823 | 590 | ==> F \<in> (A1 \<union> A2 - C) co (A1 \<union> A2 \<union> C)" | 
| 15634 | 591 | apply (unfold constrains_def st_set_def, blast) | 
| 592 | done | |
| 593 | ||
| 594 | (*Lemma (1,2,3) of Misra's draft book, Chapter 4, "Progress"*) | |
| 595 | (* slightly different from the HOL one \<in> B here is bounded *) | |
| 61392 | 596 | lemma leadsTo_123: "F \<in> A \<longmapsto> A' | 
| 597 | ==> \<exists>B \<in> Pow(state). A<=B & F \<in> B \<longmapsto> A' & F \<in> (B-A') co (B \<union> A')" | |
| 15634 | 598 | apply (frule leadsToD2) | 
| 599 | apply (erule leadsTo_induct) | |
| 60770 | 600 | txt\<open>Basis\<close> | 
| 15634 | 601 | apply (blast dest: ensuresD constrainsD2 st_setD) | 
| 60770 | 602 | txt\<open>Trans\<close> | 
| 15634 | 603 | apply clarify | 
| 46823 | 604 | apply (rule_tac x = "Ba \<union> Bb" in bexI) | 
| 15634 | 605 | apply (blast intro: leadsTo_123_aux leadsTo_Un_Un leadsTo_cancel1 leadsTo_Un_duplicate, blast) | 
| 60770 | 606 | txt\<open>Union\<close> | 
| 15634 | 607 | apply (clarify dest!: ball_conj_distrib [THEN iffD1]) | 
| 61392 | 608 | apply (subgoal_tac "\<exists>y. y \<in> Pi (S, %A. {Ba \<in> Pow (state) . A<=Ba & F \<in> Ba \<longmapsto> B & F \<in> Ba - B co Ba \<union> B}) ")
 | 
| 15634 | 609 | defer 1 | 
| 610 | apply (rule AC_ball_Pi, safe) | |
| 611 | apply (rotate_tac 1) | |
| 46953 | 612 | apply (drule_tac x = x in bspec, blast, blast) | 
| 15634 | 613 | apply (rule_tac x = "\<Union>A \<in> S. y`A" in bexI, safe) | 
| 614 | apply (rule_tac [3] I1 = S in constrains_UN [THEN constrains_weaken]) | |
| 615 | apply (rule_tac [2] leadsTo_Union) | |
| 616 | prefer 5 apply (blast dest!: apply_type, simp_all) | |
| 617 | apply (force dest!: apply_type)+ | |
| 618 | done | |
| 619 | ||
| 620 | ||
| 621 | (*Misra's property W5*) | |
| 622 | lemma wlt_constrains_wlt: "[| F \<in> program; st_set(B) |] ==>F \<in> (wlt(F, B) - B) co (wlt(F,B))" | |
| 623 | apply (cut_tac F = F in wlt_leadsTo [THEN leadsTo_123], assumption, blast) | |
| 624 | apply clarify | |
| 625 | apply (subgoal_tac "Ba = wlt (F,B) ") | |
| 626 | prefer 2 apply (blast dest: leadsTo_eq_subset_wlt [THEN iffD1], clarify) | |
| 627 | apply (simp add: wlt_increasing [THEN subset_Un_iff2 [THEN iffD1]]) | |
| 628 | done | |
| 629 | ||
| 630 | ||
| 60770 | 631 | subsection\<open>Completion: Binary and General Finite versions\<close> | 
| 15634 | 632 | |
| 46953 | 633 | lemma completion_aux: "[| W = wlt(F, (B' \<union> C)); | 
| 61392 | 634 | F \<in> A \<longmapsto> (A' \<union> C); F \<in> A' co (A' \<union> C); | 
| 635 | F \<in> B \<longmapsto> (B' \<union> C); F \<in> B' co (B' \<union> C) |] | |
| 636 | ==> F \<in> (A \<inter> B) \<longmapsto> ((A' \<inter> B') \<union> C)" | |
| 15634 | 637 | apply (subgoal_tac "st_set (C) &st_set (W) &st_set (W-C) &st_set (A') &st_set (A) & st_set (B) & st_set (B') & F \<in> program") | 
| 46953 | 638 | prefer 2 | 
| 639 | apply simp | |
| 15634 | 640 | apply (blast dest!: leadsToD2) | 
| 46823 | 641 | apply (subgoal_tac "F \<in> (W-C) co (W \<union> B' \<union> C) ") | 
| 15634 | 642 | prefer 2 | 
| 643 | apply (blast intro!: constrains_weaken [OF constrains_Un [OF _ wlt_constrains_wlt]]) | |
| 644 | apply (subgoal_tac "F \<in> (W-C) co W") | |
| 645 | prefer 2 | |
| 646 | apply (simp add: wlt_increasing [THEN subset_Un_iff2 [THEN iffD1]] Un_assoc) | |
| 61392 | 647 | apply (subgoal_tac "F \<in> (A \<inter> W - C) \<longmapsto> (A' \<inter> W \<union> C) ") | 
| 15634 | 648 | prefer 2 apply (blast intro: wlt_leadsTo psp [THEN leadsTo_weaken]) | 
| 649 | (** step 13 **) | |
| 61392 | 650 | apply (subgoal_tac "F \<in> (A' \<inter> W \<union> C) \<longmapsto> (A' \<inter> B' \<union> C) ") | 
| 15634 | 651 | apply (drule leadsTo_Diff) | 
| 652 | apply (blast intro: subset_imp_leadsTo dest: leadsToD2 constrainsD2) | |
| 653 | apply (force simp add: st_set_def) | |
| 46823 | 654 | apply (subgoal_tac "A \<inter> B \<subseteq> A \<inter> W") | 
| 15634 | 655 | prefer 2 apply (blast dest!: leadsTo_subset intro!: subset_refl [THEN Int_mono]) | 
| 656 | apply (blast intro: leadsTo_Trans subset_imp_leadsTo) | |
| 60770 | 657 | txt\<open>last subgoal\<close> | 
| 15634 | 658 | apply (rule_tac leadsTo_Un_duplicate2) | 
| 659 | apply (rule_tac leadsTo_Un_Un) | |
| 660 | prefer 2 apply (blast intro: leadsTo_refl) | |
| 46823 | 661 | apply (rule_tac A'1 = "B' \<union> C" in wlt_leadsTo[THEN psp2, THEN leadsTo_weaken]) | 
| 15634 | 662 | apply blast+ | 
| 663 | done | |
| 664 | ||
| 45602 | 665 | lemmas completion = refl [THEN completion_aux] | 
| 15634 | 666 | |
| 667 | lemma finite_completion_aux: | |
| 46953 | 668 | "[| I \<in> Fin(X); F \<in> program; st_set(C) |] ==> | 
| 61392 | 669 | (\<forall>i \<in> I. F \<in> (A(i)) \<longmapsto> (A'(i) \<union> C)) \<longrightarrow> | 
| 46953 | 670 | (\<forall>i \<in> I. F \<in> (A'(i)) co (A'(i) \<union> C)) \<longrightarrow> | 
| 61392 | 671 | F \<in> (\<Inter>i \<in> I. A(i)) \<longmapsto> ((\<Inter>i \<in> I. A'(i)) \<union> C)" | 
| 15634 | 672 | apply (erule Fin_induct) | 
| 673 | apply (auto simp add: Inter_0) | |
| 674 | apply (rule completion) | |
| 675 | apply (auto simp del: INT_simps simp add: INT_extend_simps) | |
| 676 | apply (blast intro: constrains_INT) | |
| 677 | done | |
| 678 | ||
| 46953 | 679 | lemma finite_completion: | 
| 680 | "[| I \<in> Fin(X); | |
| 61392 | 681 | !!i. i \<in> I ==> F \<in> A(i) \<longmapsto> (A'(i) \<union> C); | 
| 46953 | 682 | !!i. i \<in> I ==> F \<in> A'(i) co (A'(i) \<union> C); F \<in> program; st_set(C)|] | 
| 61392 | 683 | ==> F \<in> (\<Inter>i \<in> I. A(i)) \<longmapsto> ((\<Inter>i \<in> I. A'(i)) \<union> C)" | 
| 15634 | 684 | by (blast intro: finite_completion_aux [THEN mp, THEN mp]) | 
| 685 | ||
| 46953 | 686 | lemma stable_completion: | 
| 61392 | 687 | "[| F \<in> A \<longmapsto> A'; F \<in> stable(A'); | 
| 688 | F \<in> B \<longmapsto> B'; F \<in> stable(B') |] | |
| 689 | ==> F \<in> (A \<inter> B) \<longmapsto> (A' \<inter> B')" | |
| 15634 | 690 | apply (unfold stable_def) | 
| 691 | apply (rule_tac C1 = 0 in completion [THEN leadsTo_weaken_R], simp+) | |
| 692 | apply (blast dest: leadsToD2) | |
| 693 | done | |
| 694 | ||
| 695 | ||
| 46953 | 696 | lemma finite_stable_completion: | 
| 697 | "[| I \<in> Fin(X); | |
| 61392 | 698 | (!!i. i \<in> I ==> F \<in> A(i) \<longmapsto> A'(i)); | 
| 46953 | 699 | (!!i. i \<in> I ==> F \<in> stable(A'(i))); F \<in> program |] | 
| 61392 | 700 | ==> F \<in> (\<Inter>i \<in> I. A(i)) \<longmapsto> (\<Inter>i \<in> I. A'(i))" | 
| 15634 | 701 | apply (unfold stable_def) | 
| 702 | apply (subgoal_tac "st_set (\<Inter>i \<in> I. A' (i))") | |
| 703 | prefer 2 apply (blast dest: leadsToD2) | |
| 46953 | 704 | apply (rule_tac C1 = 0 in finite_completion [THEN leadsTo_weaken_R], auto) | 
| 15634 | 705 | done | 
| 706 | ||
| 11479 | 707 | end |