author | paulson |
Fri, 16 Nov 2001 13:48:43 +0100 | |
changeset 12220 | 9dc4e8fec63d |
parent 12215 | 55c084921240 |
child 12484 | 7ad150f5fc10 |
permissions | -rw-r--r-- |
11479 | 1 |
(* Title: ZF/UNITY/Constrains.ML |
2 |
ID: $Id$ |
|
3 |
Author: Sidi O Ehmety, Computer Laboratory |
|
4 |
Copyright 2001 University of Cambridge |
|
5 |
||
6 |
Safety relations: restricted to the set of reachable states. |
|
7 |
||
8 |
Proofs ported from HOL. |
|
9 |
*) |
|
10 |
||
11 |
(*** traces and reachable ***) |
|
12 |
||
12195 | 13 |
Goal "reachable(F) <= state"; |
14 |
by (cut_inst_tac [("F", "F")] Init_type 1); |
|
15 |
by (cut_inst_tac [("F", "F")] Acts_type 1); |
|
16 |
by (cut_inst_tac [("F", "F")] reachable.dom_subset 1); |
|
17 |
by (Blast_tac 1); |
|
11479 | 18 |
qed "reachable_type"; |
12195 | 19 |
|
20 |
Goalw [st_set_def] "st_set(reachable(F))"; |
|
21 |
by (resolve_tac [reachable_type] 1); |
|
22 |
qed "st_set_reachable"; |
|
23 |
AddIffs [st_set_reachable]; |
|
11479 | 24 |
|
12195 | 25 |
Goal "reachable(F) Int state = reachable(F)"; |
26 |
by (cut_facts_tac [reachable_type] 1); |
|
27 |
by Auto_tac; |
|
28 |
qed "reachable_Int_state"; |
|
29 |
AddIffs [reachable_Int_state]; |
|
11479 | 30 |
|
12195 | 31 |
Goal "state Int reachable(F) = reachable(F)"; |
32 |
by (cut_facts_tac [reachable_type] 1); |
|
33 |
by Auto_tac; |
|
34 |
qed "state_Int_reachable"; |
|
35 |
AddIffs [state_Int_reachable]; |
|
36 |
||
37 |
Goal |
|
38 |
"F:program ==> reachable(F)={s:state. EX evs. <s,evs>:traces(Init(F), Acts(F))}"; |
|
11479 | 39 |
by (rtac equalityI 1); |
40 |
by Safe_tac; |
|
12195 | 41 |
by (blast_tac (claset() addDs [reachable_type RS subsetD]) 1); |
11479 | 42 |
by (etac traces.induct 2); |
43 |
by (etac reachable.induct 1); |
|
44 |
by (ALLGOALS (blast_tac (claset() addIs reachable.intrs @ traces.intrs))); |
|
45 |
qed "reachable_equiv_traces"; |
|
46 |
||
47 |
Goal "Init(F) <= reachable(F)"; |
|
48 |
by (blast_tac (claset() addIs reachable.intrs) 1); |
|
49 |
qed "Init_into_reachable"; |
|
50 |
||
51 |
Goal "[| F:program; G:program; \ |
|
52 |
\ Acts(G) <= Acts(F) |] ==> G:stable(reachable(F))"; |
|
53 |
by (blast_tac (claset() |
|
12195 | 54 |
addIs [stableI, constrainsI, st_setI, |
55 |
reachable_type RS subsetD] @ reachable.intrs) 1); |
|
11479 | 56 |
qed "stable_reachable"; |
57 |
||
58 |
AddSIs [stable_reachable]; |
|
59 |
Addsimps [stable_reachable]; |
|
60 |
||
61 |
(*The set of all reachable states is an invariant...*) |
|
62 |
Goalw [invariant_def, initially_def] |
|
63 |
"F:program ==> F:invariant(reachable(F))"; |
|
12195 | 64 |
by (blast_tac (claset() addIs [reachable_type RS subsetD]@reachable.intrs) 1); |
11479 | 65 |
qed "invariant_reachable"; |
66 |
||
67 |
(*...in fact the strongest invariant!*) |
|
12195 | 68 |
Goal "F:invariant(A) ==> reachable(F) <= A"; |
69 |
by (cut_inst_tac [("F", "F")] Acts_type 1); |
|
70 |
by (cut_inst_tac [("F", "F")] Init_type 1); |
|
71 |
by (cut_inst_tac [("F", "F")] reachable_type 1); |
|
72 |
by (full_simp_tac (simpset() addsimps [stable_def, constrains_def, |
|
73 |
invariant_def, initially_def]) 1); |
|
11479 | 74 |
by (rtac subsetI 1); |
75 |
by (etac reachable.induct 1); |
|
76 |
by (REPEAT (blast_tac (claset() addIs reachable.intrs) 1)); |
|
77 |
qed "invariant_includes_reachable"; |
|
78 |
||
79 |
(*** Co ***) |
|
80 |
||
12195 | 81 |
Goal "F:B co B'==>F:(reachable(F) Int B) co (reachable(F) Int B')"; |
82 |
by (forward_tac [constrains_type RS subsetD] 1); |
|
83 |
by (forward_tac [[asm_rl, asm_rl, subset_refl] MRS stable_reachable] 1); |
|
84 |
by (ALLGOALS(asm_full_simp_tac (simpset() addsimps [stable_def, constrains_Int]))); |
|
11479 | 85 |
qed "constrains_reachable_Int"; |
86 |
||
87 |
(*Resembles the previous definition of Constrains*) |
|
88 |
Goalw [Constrains_def] |
|
12195 | 89 |
"A Co B = {F:program. F:(reachable(F) Int A) co (reachable(F) Int B)}"; |
90 |
by (blast_tac (claset() addDs [constrains_reachable_Int, |
|
91 |
constrains_type RS subsetD] |
|
11479 | 92 |
addIs [constrains_weaken]) 1); |
93 |
qed "Constrains_eq_constrains"; |
|
12195 | 94 |
val Constrains_def2 = Constrains_eq_constrains RS eq_reflection; |
95 |
||
96 |
Goalw [Constrains_def] |
|
97 |
"F:A co A' ==> F:A Co A'"; |
|
98 |
by (blast_tac (claset() addIs [constrains_weaken_L] addDs [constrainsD2]) 1); |
|
99 |
qed "constrains_imp_Constrains"; |
|
100 |
||
101 |
val prems = Goalw [Constrains_def, constrains_def, st_set_def] |
|
102 |
"[|(!!act s s'. [| act: Acts(F); <s,s'>:act; s:A |] ==> s':A'); F:program|]==>F:A Co A'"; |
|
103 |
by (auto_tac (claset(), simpset() addsimps prems)); |
|
104 |
by (blast_tac (claset() addDs [reachable_type RS subsetD]) 1); |
|
105 |
qed "ConstrainsI"; |
|
11479 | 106 |
|
107 |
Goalw [Constrains_def] |
|
12195 | 108 |
"A Co B <= program"; |
109 |
by (Blast_tac 1); |
|
110 |
qed "Constrains_type"; |
|
111 |
||
112 |
Goal "F : 0 Co B <-> F:program"; |
|
113 |
by (auto_tac (claset() addDs [Constrains_type RS subsetD] |
|
114 |
addIs [constrains_imp_Constrains], simpset())); |
|
115 |
qed "Constrains_empty"; |
|
116 |
AddIffs [Constrains_empty]; |
|
117 |
||
118 |
Goalw [Constrains_def] "F : A Co state <-> F:program"; |
|
119 |
by (auto_tac (claset() addDs [Constrains_type RS subsetD] |
|
120 |
addIs [constrains_imp_Constrains], simpset())); |
|
121 |
qed "Constrains_state"; |
|
122 |
AddIffs [Constrains_state]; |
|
123 |
||
124 |
Goalw [Constrains_def2] |
|
125 |
"[| F : A Co A'; A'<=B' |] ==> F : A Co B'"; |
|
126 |
by (blast_tac (claset() addIs [constrains_weaken_R]) 1); |
|
127 |
qed "Constrains_weaken_R"; |
|
128 |
||
129 |
Goalw [Constrains_def2] |
|
130 |
"[| F : A Co A'; B<=A |] ==> F : B Co A'"; |
|
131 |
by (blast_tac (claset() addIs [constrains_weaken_L, st_set_subset]) 1); |
|
132 |
qed "Constrains_weaken_L"; |
|
133 |
||
134 |
Goalw [Constrains_def2] |
|
135 |
"[| F : A Co A'; B<=A; A'<=B' |] ==> F : B Co B'"; |
|
136 |
by (blast_tac (claset() addIs [constrains_weaken, st_set_subset]) 1); |
|
137 |
qed "Constrains_weaken"; |
|
138 |
||
139 |
(** Union **) |
|
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
140 |
Goalw [Constrains_def2] |
12195 | 141 |
"[| F : A Co A'; F : B Co B' |] ==> F : (A Un B) Co (A' Un B')"; |
142 |
by Auto_tac; |
|
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
143 |
by (asm_full_simp_tac (simpset() addsimps [Int_Un_distrib]) 1); |
12195 | 144 |
by (blast_tac (claset() addIs [constrains_Un]) 1); |
145 |
qed "Constrains_Un"; |
|
146 |
||
147 |
val [major, minor] = Goalw [Constrains_def2] |
|
148 |
"[|(!!i. i:I==>F:A(i) Co A'(i)); F:program|] ==> F:(UN i:I. A(i)) Co (UN i:I. A'(i))"; |
|
149 |
by (cut_facts_tac [minor] 1); |
|
150 |
by (auto_tac (claset() addDs [major] |
|
151 |
addIs [constrains_UN], |
|
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
152 |
simpset() delsimps UN_simps addsimps [Int_UN_distrib])); |
12195 | 153 |
qed "Constrains_UN"; |
154 |
||
155 |
(** Intersection **) |
|
156 |
||
157 |
Goalw [Constrains_def] |
|
158 |
"[| F : A Co A'; F : B Co B'|]==> F:(A Int B) Co (A' Int B')"; |
|
159 |
by (subgoal_tac "reachable(F) Int (A Int B) = \ |
|
160 |
\ (reachable(F) Int A) Int (reachable(F) Int B)" 1); |
|
161 |
by (ALLGOALS(force_tac (claset() addIs [constrains_Int], simpset()))); |
|
162 |
qed "Constrains_Int"; |
|
163 |
||
164 |
val [major,minor] = Goal |
|
165 |
"[| (!!i. i:I ==>F: A(i) Co A'(i)); F:program |] \ |
|
166 |
\ ==> F:(INT i:I. A(i)) Co (INT i:I. A'(i))"; |
|
167 |
by (cut_facts_tac [minor] 1); |
|
12220 | 168 |
by (asm_simp_tac (simpset() delsimps INT_simps |
169 |
addsimps [Constrains_def]@INT_extend_simps) 1); |
|
12195 | 170 |
by (rtac constrains_INT 1); |
171 |
by (dresolve_tac [major] 1); |
|
12220 | 172 |
by (auto_tac (claset(), simpset() addsimps [Constrains_def])); |
12195 | 173 |
qed "Constrains_INT"; |
174 |
||
175 |
Goalw [Constrains_def] "F : A Co A' ==> reachable(F) Int A <= A'"; |
|
176 |
by (blast_tac (claset() addDs [constrains_imp_subset]) 1); |
|
177 |
qed "Constrains_imp_subset"; |
|
178 |
||
179 |
Goalw [Constrains_def2] |
|
180 |
"[| F : A Co B; F : B Co C |] ==> F : A Co C"; |
|
181 |
by (blast_tac (claset() addIs [constrains_trans, constrains_weaken]) 1); |
|
182 |
qed "Constrains_trans"; |
|
183 |
||
184 |
Goalw [Constrains_def2] |
|
185 |
"[| F : A Co (A' Un B); F : B Co B' |] ==> F : A Co (A' Un B')"; |
|
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
186 |
by (full_simp_tac (simpset() addsimps [Int_Un_distrib]) 1); |
12195 | 187 |
by (blast_tac (claset() addIs [constrains_cancel]) 1); |
188 |
qed "Constrains_cancel"; |
|
189 |
||
190 |
(*** Stable ***) |
|
191 |
(* Useful because there's no Stable_weaken. [Tanja Vos] *) |
|
11479 | 192 |
|
193 |
Goalw [stable_def, Stable_def] |
|
194 |
"F : stable(A) ==> F : Stable(A)"; |
|
195 |
by (etac constrains_imp_Constrains 1); |
|
196 |
qed "stable_imp_Stable"; |
|
197 |
||
198 |
Goal "[| F: Stable(A); A = B |] ==> F : Stable(B)"; |
|
199 |
by (Blast_tac 1); |
|
200 |
qed "Stable_eq"; |
|
201 |
||
12195 | 202 |
Goal |
203 |
"F : Stable(A) <-> (F:stable(reachable(F) Int A))"; |
|
204 |
by (auto_tac (claset() addDs [constrainsD2], |
|
205 |
simpset() addsimps [Stable_def, stable_def, Constrains_def2])); |
|
11479 | 206 |
qed "Stable_eq_stable"; |
207 |
||
12195 | 208 |
Goalw [Stable_def] "F:A Co A ==> F : Stable(A)"; |
11479 | 209 |
by (assume_tac 1); |
210 |
qed "StableI"; |
|
211 |
||
212 |
Goalw [Stable_def] "F : Stable(A) ==> F : A Co A"; |
|
213 |
by (assume_tac 1); |
|
214 |
qed "StableD"; |
|
215 |
||
216 |
Goalw [Stable_def] |
|
217 |
"[| F : Stable(A); F : Stable(A') |] ==> F : Stable(A Un A')"; |
|
218 |
by (blast_tac (claset() addIs [Constrains_Un]) 1); |
|
219 |
qed "Stable_Un"; |
|
220 |
||
221 |
Goalw [Stable_def] |
|
222 |
"[| F : Stable(A); F : Stable(A') |] ==> F : Stable (A Int A')"; |
|
223 |
by (blast_tac (claset() addIs [Constrains_Int]) 1); |
|
224 |
qed "Stable_Int"; |
|
225 |
||
226 |
Goalw [Stable_def] |
|
227 |
"[| F : Stable(C); F : A Co (C Un A') |] \ |
|
228 |
\ ==> F : (C Un A) Co (C Un A')"; |
|
229 |
by (blast_tac (claset() addIs [Constrains_Un RS Constrains_weaken_R]) 1); |
|
230 |
qed "Stable_Constrains_Un"; |
|
231 |
||
232 |
Goalw [Stable_def] |
|
233 |
"[| F : Stable(C); F : (C Int A) Co A' |] \ |
|
234 |
\ ==> F : (C Int A) Co (C Int A')"; |
|
12195 | 235 |
by (blast_tac (claset() addIs [Constrains_Int RS Constrains_weaken]) 1); |
11479 | 236 |
qed "Stable_Constrains_Int"; |
237 |
||
12195 | 238 |
val [major,minor] = Goalw [Stable_def] |
239 |
"[| (!!i. i:I ==> F : Stable(A(i))); F:program |]==> F : Stable (UN i:I. A(i))"; |
|
240 |
by (cut_facts_tac [minor] 1); |
|
241 |
by (blast_tac (claset() addIs [Constrains_UN,major]) 1); |
|
11479 | 242 |
qed "Stable_UN"; |
243 |
||
12195 | 244 |
val [major,minor] = Goalw [Stable_def] |
245 |
"[|(!!i. i:I ==> F:Stable(A(i))); F:program |]==> F : Stable (INT i:I. A(i))"; |
|
246 |
by (cut_facts_tac [minor] 1); |
|
247 |
by (blast_tac (claset() addIs [Constrains_INT, major]) 1); |
|
11479 | 248 |
qed "Stable_INT"; |
249 |
||
250 |
Goal "F:program ==>F : Stable (reachable(F))"; |
|
251 |
by (asm_simp_tac (simpset() |
|
12195 | 252 |
addsimps [Stable_eq_stable, Int_absorb]) 1); |
11479 | 253 |
qed "Stable_reachable"; |
254 |
||
255 |
Goalw [Stable_def] |
|
12195 | 256 |
"Stable(A) <= program"; |
257 |
by (rtac Constrains_type 1); |
|
258 |
qed "Stable_type"; |
|
11479 | 259 |
|
260 |
(*** The Elimination Theorem. The "free" m has become universally quantified! |
|
261 |
Should the premise be !!m instead of ALL m ? Would make it harder to use |
|
262 |
in forward proof. ***) |
|
263 |
||
12195 | 264 |
Goalw [Constrains_def] |
265 |
"[| ALL m:M. F : ({s:A. x(s) = m}) Co (B(m)); F:program |] \ |
|
266 |
\ ==> F : ({s:A. x(s):M}) Co (UN m:M. B(m))"; |
|
11479 | 267 |
by Auto_tac; |
12195 | 268 |
by (res_inst_tac [("A1","reachable(F)Int A")] (elimination RS constrains_weaken_L) 1); |
269 |
by (auto_tac (claset() addIs [constrains_weaken_L], simpset())); |
|
11479 | 270 |
qed "Elimination"; |
271 |
||
12195 | 272 |
(* As above, but for the special case of A=state *) |
11479 | 273 |
Goal |
274 |
"[| ALL m:M. F : {s:state. x(s) = m} Co B(m); F:program |] \ |
|
275 |
\ ==> F : {s:state. x(s):M} Co (UN m:M. B(m))"; |
|
276 |
by (blast_tac (claset() addIs [Elimination]) 1); |
|
277 |
qed "Elimination2"; |
|
278 |
||
279 |
(** Unless **) |
|
280 |
||
12195 | 281 |
Goalw [Unless_def] "A Unless B <=program"; |
282 |
by (rtac Constrains_type 1); |
|
283 |
qed "Unless_type"; |
|
11479 | 284 |
|
285 |
(*** Specialized laws for handling Always ***) |
|
286 |
||
287 |
(** Natural deduction rules for "Always A" **) |
|
12195 | 288 |
|
11479 | 289 |
Goalw [Always_def, initially_def] |
290 |
"[| Init(F)<=A; F : Stable(A) |] ==> F : Always(A)"; |
|
12195 | 291 |
by (forward_tac [Stable_type RS subsetD] 1); |
292 |
by Auto_tac; |
|
11479 | 293 |
qed "AlwaysI"; |
294 |
||
295 |
Goal "F : Always(A) ==> Init(F)<=A & F : Stable(A)"; |
|
12195 | 296 |
by (asm_full_simp_tac (simpset() addsimps [Always_def, initially_def]) 1); |
11479 | 297 |
qed "AlwaysD"; |
298 |
||
299 |
bind_thm ("AlwaysE", AlwaysD RS conjE); |
|
300 |
bind_thm ("Always_imp_Stable", AlwaysD RS conjunct2); |
|
301 |
||
302 |
(*The set of all reachable states is Always*) |
|
303 |
Goal "F : Always(A) ==> reachable(F) <= A"; |
|
12195 | 304 |
by (full_simp_tac (simpset() addsimps |
305 |
[Stable_def, Constrains_def, constrains_def, Always_def, initially_def]) 1); |
|
11479 | 306 |
by (rtac subsetI 1); |
307 |
by (etac reachable.induct 1); |
|
308 |
by (REPEAT (blast_tac (claset() addIs reachable.intrs) 1)); |
|
309 |
qed "Always_includes_reachable"; |
|
310 |
||
12195 | 311 |
Goalw [Always_def, invariant_def, Stable_def, stable_def] |
11479 | 312 |
"F : invariant(A) ==> F : Always(A)"; |
313 |
by (blast_tac (claset() addIs [constrains_imp_Constrains]) 1); |
|
314 |
qed "invariant_imp_Always"; |
|
315 |
||
316 |
bind_thm ("Always_reachable", invariant_reachable RS invariant_imp_Always); |
|
317 |
||
12195 | 318 |
Goal "Always(A) = {F:program. F : invariant(reachable(F) Int A)}"; |
11479 | 319 |
by (simp_tac (simpset() addsimps [Always_def, invariant_def, Stable_def, |
12195 | 320 |
Constrains_def2, stable_def, initially_def]) 1); |
11479 | 321 |
by (rtac equalityI 1); |
322 |
by (ALLGOALS(Clarify_tac)); |
|
12195 | 323 |
by (REPEAT(blast_tac (claset() addIs reachable.intrs@[reachable_type]) 1)); |
11479 | 324 |
qed "Always_eq_invariant_reachable"; |
325 |
||
326 |
(*the RHS is the traditional definition of the "always" operator*) |
|
12195 | 327 |
Goal "Always(A) = {F:program. reachable(F) <= A}"; |
11479 | 328 |
br equalityI 1; |
329 |
by (ALLGOALS(Clarify_tac)); |
|
330 |
by (auto_tac (claset() addDs [invariant_includes_reachable], |
|
331 |
simpset() addsimps [subset_Int_iff, invariant_reachable, |
|
332 |
Always_eq_invariant_reachable])); |
|
333 |
qed "Always_eq_includes_reachable"; |
|
334 |
||
12195 | 335 |
Goalw [Always_def, initially_def] "Always(A) <= program"; |
336 |
by Auto_tac; |
|
337 |
qed "Always_type"; |
|
11479 | 338 |
|
339 |
Goal "Always(state) = program"; |
|
340 |
br equalityI 1; |
|
12195 | 341 |
by (auto_tac (claset() addDs [Always_type RS subsetD, |
342 |
reachable_type RS subsetD], |
|
343 |
simpset() addsimps [Always_eq_includes_reachable])); |
|
11479 | 344 |
qed "Always_state_eq"; |
345 |
Addsimps [Always_state_eq]; |
|
346 |
||
12195 | 347 |
Goal "F:program ==> F : Always(state)"; |
348 |
by (auto_tac (claset() addDs [reachable_type RS subsetD], simpset() |
|
11479 | 349 |
addsimps [Always_eq_includes_reachable])); |
350 |
qed "state_AlwaysI"; |
|
351 |
||
12195 | 352 |
Goal "st_set(A) ==> Always(A) = (UN I: Pow(A). invariant(I))"; |
11479 | 353 |
by (simp_tac (simpset() addsimps [Always_eq_includes_reachable]) 1); |
354 |
by (rtac equalityI 1); |
|
355 |
by (ALLGOALS(Clarify_tac)); |
|
356 |
by (REPEAT(blast_tac (claset() |
|
357 |
addIs [invariantI, impOfSubs Init_into_reachable, |
|
358 |
impOfSubs invariant_includes_reachable] |
|
12195 | 359 |
addDs [invariant_type RS subsetD]) 1)); |
11479 | 360 |
qed "Always_eq_UN_invariant"; |
361 |
||
12195 | 362 |
Goal "[| F : Always(A); A <= B |] ==> F : Always(B)"; |
11479 | 363 |
by (auto_tac (claset(), simpset() addsimps [Always_eq_includes_reachable])); |
364 |
qed "Always_weaken"; |
|
365 |
||
366 |
||
367 |
(*** "Co" rules involving Always ***) |
|
368 |
val Int_absorb2 = rewrite_rule [iff_def] subset_Int_iff RS conjunct1 RS mp; |
|
369 |
||
12195 | 370 |
Goal "F:Always(I) ==> (F:(I Int A) Co A') <-> (F : A Co A')"; |
11479 | 371 |
by (asm_simp_tac |
372 |
(simpset() addsimps [Always_includes_reachable RS Int_absorb2, |
|
373 |
Constrains_def, Int_assoc RS sym]) 1); |
|
374 |
qed "Always_Constrains_pre"; |
|
375 |
||
12195 | 376 |
Goal "F:Always(I) ==> (F : A Co (I Int A')) <->(F : A Co A')"; |
11479 | 377 |
by (asm_simp_tac |
378 |
(simpset() addsimps [Always_includes_reachable RS Int_absorb2, |
|
379 |
Constrains_eq_constrains, Int_assoc RS sym]) 1); |
|
380 |
qed "Always_Constrains_post"; |
|
381 |
||
12195 | 382 |
Goal "[| F : Always(I); F : (I Int A) Co A' |] ==> F : A Co A'"; |
383 |
by (blast_tac (claset() addIs [Always_Constrains_pre RS iffD1]) 1); |
|
384 |
qed "Always_ConstrainsI"; |
|
11479 | 385 |
|
12195 | 386 |
(* [| F : Always(I); F : A Co A' |] ==> F : A Co (I Int A') *) |
11479 | 387 |
bind_thm ("Always_ConstrainsD", Always_Constrains_post RS iffD2); |
388 |
||
389 |
(*The analogous proof of Always_LeadsTo_weaken doesn't terminate*) |
|
12195 | 390 |
Goal |
391 |
"[|F:Always(C); F:A Co A'; C Int B<=A; C Int A'<=B'|]==>F:B Co B'"; |
|
11479 | 392 |
by (rtac Always_ConstrainsI 1); |
12195 | 393 |
by (dtac Always_ConstrainsD 2); |
394 |
by (ALLGOALS(Asm_simp_tac)); |
|
11479 | 395 |
by (blast_tac (claset() addIs [Constrains_weaken]) 1); |
396 |
qed "Always_Constrains_weaken"; |
|
397 |
||
398 |
(** Conjoining Always properties **) |
|
12195 | 399 |
Goal "Always(A Int B) = Always(A) Int Always(B)"; |
11479 | 400 |
by (auto_tac (claset(), simpset() addsimps [Always_eq_includes_reachable])); |
401 |
qed "Always_Int_distrib"; |
|
402 |
||
403 |
(* the premise i:I is need since INT is formally not defined for I=0 *) |
|
12195 | 404 |
Goal "i:I==>Always(INT i:I. A(i)) = (INT i:I. Always(A(i)))"; |
11479 | 405 |
by (rtac equalityI 1); |
12195 | 406 |
by (auto_tac (claset(), simpset() addsimps |
407 |
[Inter_iff, Always_eq_includes_reachable])); |
|
11479 | 408 |
qed "Always_INT_distrib"; |
409 |
||
410 |
||
12195 | 411 |
Goal "[| F:Always(A); F:Always(B) |] ==> F:Always(A Int B)"; |
412 |
by (asm_simp_tac (simpset() addsimps [Always_Int_distrib]) 1); |
|
11479 | 413 |
qed "Always_Int_I"; |
414 |
||
415 |
(*Allows a kind of "implication introduction"*) |
|
12195 | 416 |
Goal "[| F:Always(A) |] ==> (F : Always(C-A Un B)) <-> (F : Always(B))"; |
11479 | 417 |
by (auto_tac (claset(), simpset() addsimps [Always_eq_includes_reachable])); |
12195 | 418 |
qed "Always_Diff_Un_eq"; |
11479 | 419 |
|
420 |
(*Delete the nearest invariance assumption (which will be the second one |
|
421 |
used by Always_Int_I) *) |
|
422 |
val Always_thin = |
|
423 |
read_instantiate_sg (sign_of thy) |
|
424 |
[("V", "?F : Always(?A)")] thin_rl; |
|
425 |
||
426 |
(*Combines two invariance ASSUMPTIONS into one. USEFUL??*) |
|
427 |
val Always_Int_tac = dtac Always_Int_I THEN' assume_tac THEN' etac Always_thin; |
|
428 |
||
429 |
(*Combines a list of invariance THEOREMS into one.*) |
|
430 |
val Always_Int_rule = foldr1 (fn (th1,th2) => [th1,th2] MRS Always_Int_I); |
|
431 |
||
432 |
(*** Increasing ***) |
|
433 |
||
12195 | 434 |
Goalw [Increasing_def] "Increasing(A,r,f) <= program"; |
435 |
by (auto_tac (claset() addDs [Stable_type RS subsetD] |
|
436 |
addSDs [bspec], simpset() addsimps [INT_iff])); |
|
437 |
qed "Increasing_type"; |
|
438 |
||
439 |
Goalw [Increasing_def] |
|
440 |
"[| F:Increasing(A, r, f); a:A |] ==> F: Stable({s:state. <a,f`s>:r})"; |
|
11479 | 441 |
by (Blast_tac 1); |
12195 | 442 |
qed "IncreasingD"; |
11479 | 443 |
|
12195 | 444 |
Goalw [Increasing_def] |
445 |
"F:Increasing(A, r, f) ==> F:program & (EX a. a:A)"; |
|
11479 | 446 |
by (auto_tac (claset(), simpset() addsimps [INT_iff])); |
12195 | 447 |
by (blast_tac (claset() addDs [Stable_type RS subsetD]) 1); |
448 |
qed "IncreasingD2"; |
|
449 |
||
450 |
Goalw [increasing_def, Increasing_def] |
|
451 |
"F : increasing(A, r, f) ==> F : Increasing(A, r, f)"; |
|
452 |
by (asm_full_simp_tac (simpset() addsimps [INT_iff]) 1); |
|
453 |
by (blast_tac (claset() addIs [stable_imp_Stable]) 1); |
|
454 |
qed "increasing_imp_Increasing"; |
|
11479 | 455 |
|
12220 | 456 |
Goal "F:Increasing(A, r, lam x:state. c) <-> F:program & (EX a. a:A)"; |
12195 | 457 |
by (auto_tac (claset() addDs [IncreasingD2] |
458 |
addIs [increasing_imp_Increasing], simpset())); |
|
459 |
qed "Increasing_constant"; |
|
460 |
AddIffs [Increasing_constant]; |
|
461 |
||
462 |
Goalw [Increasing_def, Stable_def, stable_def, Constrains_def, |
|
463 |
constrains_def, part_order_def, st_set_def] |
|
464 |
"[| g:mono_map(A,r,A,r); part_order(A, r); f:state->A |] \ |
|
465 |
\ ==> Increasing(A, r,f) <= Increasing(A, r,g O f)"; |
|
466 |
by (case_tac "A=0" 1); |
|
467 |
by (Asm_full_simp_tac 1); |
|
468 |
by (etac not_emptyE 1); |
|
469 |
by (Clarify_tac 1); |
|
470 |
by (cut_inst_tac [("F", "xa")] Acts_type 1); |
|
471 |
by (asm_full_simp_tac (simpset() addsimps [Inter_iff, mono_map_def]) 1); |
|
472 |
by Auto_tac; |
|
473 |
by (dres_inst_tac [("psi", "ALL x:A. ALL xa:A. ?u(x,xa)")] asm_rl 1); |
|
474 |
by (dres_inst_tac [("x", "f`xf")] bspec 1); |
|
475 |
by Auto_tac; |
|
476 |
by (dres_inst_tac [("psi", "ALL x:A. ALL xa:A. ?u(x,xa)")] asm_rl 1); |
|
12152
46f128d8133c
Renamed some bound variables due to changes in simplifier.
berghofe
parents:
11479
diff
changeset
|
477 |
by (dres_inst_tac [("x", "act")] bspec 1); |
12195 | 478 |
by Auto_tac; |
479 |
by (dres_inst_tac [("psi", "Acts(?u) <= ?v")] asm_rl 1); |
|
480 |
by (dres_inst_tac [("psi", "?u <= state")] asm_rl 1); |
|
481 |
by (dres_inst_tac [("c", "xe")] subsetD 1); |
|
11479 | 482 |
by (rtac imageI 1); |
483 |
by Auto_tac; |
|
12195 | 484 |
by (asm_full_simp_tac (simpset() addsimps [refl_def, apply_type]) 1); |
485 |
by (dres_inst_tac [("x1", "f`xf"), ("x", "f`xe")] (bspec RS bspec) 1); |
|
486 |
by (ALLGOALS(asm_full_simp_tac (simpset() addsimps [apply_type]))); |
|
487 |
by (res_inst_tac [("b", "g ` (f ` xf)")] trans_onD 1); |
|
488 |
by (ALLGOALS(asm_full_simp_tac (simpset() addsimps [apply_type]))); |
|
489 |
qed "mono_Increasing_comp"; |
|
11479 | 490 |
|
12195 | 491 |
Goalw [Increasing_def] |
492 |
"[| F:Increasing(nat, {<m,n>:nat*nat. m le n}, f); f:state->nat; k:nat |] \ |
|
493 |
\ ==> F: Stable({s:state. k < f`s})"; |
|
11479 | 494 |
by (Clarify_tac 1); |
495 |
by (asm_full_simp_tac (simpset() addsimps [INT_iff]) 1); |
|
496 |
by Safe_tac; |
|
12195 | 497 |
by (dres_inst_tac [("x", "succ(k)")] bspec 1); |
11479 | 498 |
by (auto_tac (claset(), simpset() addsimps [apply_type, Collect_conj_eq])); |
12195 | 499 |
by (subgoal_tac "{x: state . f`x : nat} = state" 1); |
11479 | 500 |
by Auto_tac; |
12195 | 501 |
qed "strict_IncreasingD"; |
11479 | 502 |
|
503 |
(*To allow expansion of the program's definition when appropriate*) |
|
504 |
val program_defs_ref = ref ([] : thm list); |
|
505 |
||
506 |
(*proves "co" properties when the program is specified*) |
|
507 |
||
508 |
fun constrains_tac i = |
|
509 |
SELECT_GOAL |
|
510 |
(EVERY [REPEAT (Always_Int_tac 1), |
|
511 |
REPEAT (etac Always_ConstrainsI 1 |
|
512 |
ORELSE |
|
513 |
resolve_tac [StableI, stableI, |
|
514 |
constrains_imp_Constrains] 1), |
|
515 |
rtac constrainsI 1, |
|
12195 | 516 |
(* Three subgoals *) |
517 |
rewrite_goal_tac [st_set_def] 3, |
|
518 |
REPEAT (Force_tac 2), |
|
11479 | 519 |
full_simp_tac (simpset() addsimps !program_defs_ref) 1, |
520 |
ALLGOALS Clarify_tac, |
|
521 |
REPEAT (FIRSTGOAL (etac disjE)), |
|
522 |
ALLGOALS Clarify_tac, |
|
523 |
REPEAT (FIRSTGOAL (etac disjE)), |
|
524 |
ALLGOALS Clarify_tac, |
|
525 |
ALLGOALS Asm_full_simp_tac, |
|
526 |
ALLGOALS Clarify_tac]) i; |
|
527 |
||
528 |
(*For proving invariants*) |
|
529 |
fun always_tac i = |
|
530 |
rtac AlwaysI i THEN Force_tac i THEN constrains_tac i; |