author | wenzelm |
Tue, 11 Dec 2001 16:00:26 +0100 | |
changeset 12466 | 5f4182667032 |
parent 12220 | 9dc4e8fec63d |
child 12484 | 7ad150f5fc10 |
permissions | -rw-r--r-- |
11479 | 1 |
(* Title: ZF/UNITY/Union.ML |
2 |
ID: $Id$ |
|
3 |
Author: Sidi O Ehmety, Computer Laboratory |
|
4 |
Copyright 2001 University of Cambridge |
|
5 |
||
6 |
Unions of programs |
|
7 |
||
8 |
From Misra's Chapter 5: Asynchronous Compositions of Programs |
|
9 |
||
10 |
Proofs ported from HOL. |
|
11 |
||
12 |
*) |
|
13 |
||
14 |
(** SKIP **) |
|
15 |
||
16 |
Goal "reachable(SKIP) = state"; |
|
17 |
by (force_tac (claset() addEs [reachable.induct] |
|
18 |
addIs reachable.intrs, simpset()) 1); |
|
19 |
qed "reachable_SKIP"; |
|
12195 | 20 |
AddIffs [reachable_SKIP]; |
11479 | 21 |
|
22 |
(* Elimination programify from ok and Join *) |
|
23 |
||
24 |
Goal "programify(F) ok G <-> F ok G"; |
|
25 |
by (simp_tac (simpset() addsimps [ok_def]) 1); |
|
26 |
qed "ok_programify_left"; |
|
27 |
||
28 |
Goal "F ok programify(G) <-> F ok G"; |
|
29 |
by (simp_tac (simpset() addsimps [ok_def]) 1); |
|
30 |
qed "ok_programify_right"; |
|
31 |
||
32 |
Goal "programify(F) Join G = F Join G"; |
|
33 |
by (simp_tac (simpset() addsimps [Join_def]) 1); |
|
34 |
qed "Join_programify_left"; |
|
35 |
||
36 |
Goal "F Join programify(G) = F Join G"; |
|
37 |
by (simp_tac (simpset() addsimps [Join_def]) 1); |
|
38 |
qed "Join_programify_right"; |
|
39 |
||
12195 | 40 |
AddIffs [ok_programify_left, ok_programify_right, |
11479 | 41 |
Join_programify_left, Join_programify_right]; |
42 |
||
43 |
(** SKIP and safety properties **) |
|
44 |
||
12195 | 45 |
Goalw [constrains_def, st_set_def] |
46 |
"(SKIP: A co B) <-> (A<=B & st_set(A))"; |
|
11479 | 47 |
by Auto_tac; |
48 |
qed "SKIP_in_constrains_iff"; |
|
12195 | 49 |
AddIffs [SKIP_in_constrains_iff]; |
11479 | 50 |
|
12195 | 51 |
Goalw [Constrains_def]"(SKIP : A Co B)<-> (state Int A<=B)"; |
52 |
by Auto_tac; |
|
11479 | 53 |
qed "SKIP_in_Constrains_iff"; |
12195 | 54 |
AddIffs [SKIP_in_Constrains_iff]; |
11479 | 55 |
|
12195 | 56 |
Goal "SKIP:stable(A) <-> st_set(A)"; |
11479 | 57 |
by (auto_tac (claset(), |
58 |
simpset() addsimps [stable_def])); |
|
59 |
qed "SKIP_in_stable"; |
|
12195 | 60 |
AddIffs [SKIP_in_stable]; |
11479 | 61 |
|
12195 | 62 |
Goalw [Stable_def] "SKIP:Stable(A)"; |
63 |
by Auto_tac; |
|
64 |
qed "SKIP_in_Stable"; |
|
65 |
AddIffs [SKIP_in_Stable]; |
|
11479 | 66 |
|
67 |
(** Join and JOIN types **) |
|
68 |
||
12195 | 69 |
Goalw [Join_def] "F Join G : program"; |
11479 | 70 |
by Auto_tac; |
71 |
qed "Join_in_program"; |
|
72 |
AddIffs [Join_in_program]; |
|
73 |
AddTCs [Join_in_program]; |
|
74 |
||
12195 | 75 |
Goalw [JOIN_def] "JOIN(I,F):program"; |
11479 | 76 |
by Auto_tac; |
77 |
qed "JOIN_in_program"; |
|
78 |
AddIffs [JOIN_in_program]; |
|
79 |
AddTCs [JOIN_in_program]; |
|
80 |
||
81 |
(* Init, Acts, and AllowedActs of Join and JOIN *) |
|
82 |
Goal "Init(F Join G) = Init(F) Int Init(G)"; |
|
83 |
by (simp_tac (simpset() |
|
84 |
addsimps [Int_assoc, Join_def]) 1); |
|
85 |
qed "Init_Join"; |
|
86 |
||
87 |
Goal "Acts(F Join G) = Acts(F) Un Acts(G)"; |
|
12220 | 88 |
by (simp_tac (simpset() addsimps [Int_Un_distrib2, cons_absorb, Join_def]) 1); |
11479 | 89 |
qed "Acts_Join"; |
90 |
||
91 |
Goal "AllowedActs(F Join G) = \ |
|
92 |
\ AllowedActs(F) Int AllowedActs(G)"; |
|
93 |
by (simp_tac (simpset() |
|
94 |
addsimps [Int_assoc,cons_absorb,Join_def]) 1); |
|
95 |
qed "AllowedActs_Join"; |
|
96 |
Addsimps [Init_Join, Acts_Join, AllowedActs_Join]; |
|
97 |
||
98 |
(** Join's algebraic laws **) |
|
99 |
||
100 |
Goal "F Join G = G Join F"; |
|
101 |
by (simp_tac (simpset() addsimps |
|
102 |
[Join_def, Un_commute, Int_commute]) 1); |
|
103 |
qed "Join_commute"; |
|
104 |
||
105 |
Goal "A Join (B Join C) = B Join (A Join C)"; |
|
12220 | 106 |
by (asm_simp_tac (simpset() addsimps |
107 |
Un_ac@Int_ac@[Join_def,Int_Un_distrib2, cons_absorb]) 1); |
|
11479 | 108 |
qed "Join_left_commute"; |
109 |
||
110 |
Goal "(F Join G) Join H = F Join (G Join H)"; |
|
111 |
by (asm_simp_tac (simpset() addsimps |
|
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
112 |
Un_ac@[Join_def, cons_absorb, Int_assoc, Int_Un_distrib2]) 1); |
11479 | 113 |
qed "Join_assoc"; |
114 |
||
12195 | 115 |
(* Needed below *) |
116 |
Goal "cons(id(state), Pow(state * state)) = Pow(state*state)"; |
|
117 |
by Auto_tac; |
|
118 |
qed "cons_id"; |
|
119 |
AddIffs [cons_id]; |
|
120 |
||
11479 | 121 |
Goalw [Join_def, SKIP_def] |
122 |
"SKIP Join F = programify(F)"; |
|
12195 | 123 |
by (auto_tac (claset(), simpset() addsimps [Int_absorb,cons_eq])); |
11479 | 124 |
qed "Join_SKIP_left"; |
125 |
||
126 |
Goal "F Join SKIP = programify(F)"; |
|
127 |
by (stac Join_commute 1); |
|
128 |
by (asm_simp_tac (simpset() addsimps [Join_SKIP_left]) 1); |
|
129 |
qed "Join_SKIP_right"; |
|
130 |
||
12195 | 131 |
AddIffs [Join_SKIP_left, Join_SKIP_right]; |
11479 | 132 |
|
133 |
Goal "F Join F = programify(F)"; |
|
134 |
by (rtac program_equalityI 1); |
|
135 |
by Auto_tac; |
|
136 |
qed "Join_absorb"; |
|
137 |
||
138 |
Addsimps [Join_absorb]; |
|
139 |
||
140 |
Goal "F Join (F Join G) = F Join G"; |
|
141 |
by (asm_simp_tac (simpset() addsimps [Join_assoc RS sym]) 1); |
|
142 |
qed "Join_left_absorb"; |
|
143 |
||
144 |
(*Join is an AC-operator*) |
|
145 |
val Join_ac = [Join_assoc, Join_left_absorb, Join_commute, Join_left_commute]; |
|
146 |
||
12195 | 147 |
(** Eliminating programify form JN and OK expressions **) |
11479 | 148 |
|
149 |
Goal "OK(I, %x. programify(F(x))) <-> OK(I, F)"; |
|
150 |
by (simp_tac (simpset() addsimps [OK_def]) 1); |
|
151 |
qed "OK_programify"; |
|
152 |
||
153 |
Goal "JOIN(I, %x. programify(F(x))) = JOIN(I, F)"; |
|
154 |
by (simp_tac (simpset() addsimps [JOIN_def]) 1); |
|
155 |
qed "JN_programify"; |
|
156 |
||
12195 | 157 |
AddIffs [OK_programify, JN_programify]; |
11479 | 158 |
|
159 |
(* JN *) |
|
160 |
||
12195 | 161 |
Goalw [JOIN_def] "JOIN(0, F) = SKIP"; |
11479 | 162 |
by Auto_tac; |
163 |
qed "JN_empty"; |
|
12195 | 164 |
AddIffs [JN_empty]; |
11479 | 165 |
AddSEs [not_emptyE]; |
166 |
Addsimps [Inter_0]; |
|
167 |
||
12220 | 168 |
Goal "Init(JN i:I. F(i)) = (if I=0 then state else (INT i:I. Init(F(i))))"; |
169 |
by (simp_tac (simpset() addsimps [JOIN_def]) 1); |
|
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
170 |
by (auto_tac (claset(), simpset() addsimps [INT_Int_distrib])); |
11479 | 171 |
qed "Init_JN"; |
172 |
||
12195 | 173 |
Goalw [JOIN_def] |
12220 | 174 |
"Acts(JOIN(I,F)) = cons(id(state), UN i:I. Acts(F(i)))"; |
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
175 |
by (auto_tac (claset(), simpset() delsimps (INT_simps@UN_simps))); |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
176 |
by (rtac equalityI 1); |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
177 |
by (auto_tac (claset() addDs [Acts_type RS subsetD], simpset())); |
11479 | 178 |
qed "Acts_JN"; |
179 |
||
12195 | 180 |
Goalw [JOIN_def] |
181 |
"AllowedActs(JN i:I. F(i)) = (if I=0 then Pow(state*state) else (INT i:I. AllowedActs(F(i))))"; |
|
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
182 |
by Auto_tac; |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
183 |
by (rtac equalityI 1); |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
184 |
by (auto_tac (claset() addDs [AllowedActs_type RS subsetD], simpset())); |
11479 | 185 |
qed "AllowedActs_JN"; |
12195 | 186 |
AddIffs [Init_JN, Acts_JN, AllowedActs_JN]; |
11479 | 187 |
|
188 |
Goal "(JN i:cons(a,I). F(i)) = F(a) Join (JN i:I. F(i))"; |
|
189 |
by (rtac program_equalityI 1); |
|
190 |
by Auto_tac; |
|
191 |
qed "JN_cons"; |
|
12195 | 192 |
AddIffs[JN_cons]; |
11479 | 193 |
|
194 |
||
195 |
val prems = Goalw [JOIN_def] |
|
196 |
"[| I=J; !!i. i:J ==> F(i) = G(i) |] ==> \ |
|
197 |
\ (JN i:I. F(i)) = (JN i:J. G(i))"; |
|
198 |
by (asm_simp_tac (simpset() addsimps prems) 1); |
|
199 |
qed "JN_cong"; |
|
200 |
||
201 |
Addcongs [JN_cong]; |
|
202 |
||
203 |
(*** JN laws ***) |
|
204 |
Goal "k:I ==>F(k) Join (JN i:I. F(i)) = (JN i:I. F(i))"; |
|
205 |
by (stac (JN_cons RS sym) 1); |
|
206 |
by (auto_tac (claset(), |
|
207 |
simpset() addsimps [cons_absorb])); |
|
208 |
qed "JN_absorb"; |
|
209 |
||
210 |
Goal "(JN i: I Un J. F(i)) = ((JN i: I. F(i)) Join (JN i:J. F(i)))"; |
|
211 |
by (rtac program_equalityI 1); |
|
12220 | 212 |
by (ALLGOALS(asm_full_simp_tac (simpset() addsimps [UN_Un,INT_Un]))); |
213 |
by (ALLGOALS(asm_full_simp_tac (simpset() delsimps INT_simps |
|
214 |
addsimps INT_extend_simps))); |
|
215 |
by (Blast_tac 1); |
|
11479 | 216 |
qed "JN_Un"; |
217 |
||
218 |
Goal "(JN i:I. c) = (if I=0 then SKIP else programify(c))"; |
|
219 |
by (rtac program_equalityI 1); |
|
220 |
by Auto_tac; |
|
221 |
qed "JN_constant"; |
|
222 |
||
12220 | 223 |
Goal "(JN i:I. F(i) Join G(i)) = (JN i:I. F(i)) Join (JN i:I. G(i))"; |
11479 | 224 |
by (rtac program_equalityI 1); |
225 |
by (ALLGOALS(simp_tac (simpset() addsimps [Int_absorb]))); |
|
226 |
by Safe_tac; |
|
227 |
by (ALLGOALS(asm_full_simp_tac (simpset() addsimps |
|
228 |
[INT_Int_distrib, Int_absorb]))); |
|
229 |
by (Force_tac 1); |
|
230 |
qed "JN_Join_distrib"; |
|
231 |
||
12220 | 232 |
Goal "(JN i:I. F(i) Join G) = ((JN i:I. F(i) Join G))"; |
11479 | 233 |
by (asm_simp_tac (simpset() |
234 |
addsimps [JN_Join_distrib, JN_constant]) 1); |
|
235 |
qed "JN_Join_miniscope"; |
|
236 |
||
237 |
(*Used to prove guarantees_JN_I*) |
|
238 |
||
239 |
Goal "i:I==>F(i) Join JOIN(I - {i}, F) = JOIN(I, F)"; |
|
240 |
by (rtac program_equalityI 1); |
|
241 |
by Auto_tac; |
|
242 |
qed "JN_Join_diff"; |
|
243 |
||
244 |
(*** Safety: co, stable, FP ***) |
|
245 |
||
246 |
||
247 |
(*Fails if I=0 because it collapses to SKIP : A co B, i.e. to A<=B. So an |
|
248 |
alternative precondition is A<=B, but most proofs using this rule require |
|
249 |
I to be nonempty for other reasons anyway.*) |
|
250 |
||
12195 | 251 |
Goalw [constrains_def, JOIN_def,st_set_def] |
11479 | 252 |
"i:I==>(JN i:I. F(i)):A co B <-> (ALL i:I. programify(F(i)):A co B)"; |
253 |
by Auto_tac; |
|
12195 | 254 |
by (cut_inst_tac [("F","F(xa)")] Acts_type 1); |
255 |
by (Blast_tac 2); |
|
256 |
by (dres_inst_tac [("x", "xb")] bspec 1); |
|
257 |
by Auto_tac; |
|
11479 | 258 |
qed "JN_constrains"; |
259 |
||
12195 | 260 |
Goal "(F Join G : A co B) <-> (programify(F):A co B & programify(G):A co B)"; |
11479 | 261 |
by (auto_tac |
262 |
(claset(), simpset() addsimps [constrains_def])); |
|
263 |
qed "Join_constrains"; |
|
264 |
||
265 |
Goal "(F Join G : A unless B) <-> \ |
|
266 |
\ (programify(F) : A unless B & programify(G):A unless B)"; |
|
267 |
by (asm_simp_tac (simpset() addsimps [Join_constrains, unless_def]) 1); |
|
268 |
qed "Join_unless"; |
|
269 |
||
12195 | 270 |
AddIffs [Join_constrains, Join_unless]; |
11479 | 271 |
|
272 |
(*Analogous weak versions FAIL; see Misra [1994] 5.4.1, Substitution Axiom. |
|
273 |
reachable (F Join G) could be much bigger than reachable F, reachable G |
|
274 |
*) |
|
275 |
||
276 |
Goal "[| F : A co A'; G:B co B' |] \ |
|
277 |
\ ==> F Join G : (A Int B) co (A' Un B')"; |
|
12195 | 278 |
by (subgoal_tac "st_set(A) & st_set(B) & F:program & G:program" 1); |
11479 | 279 |
by (blast_tac (claset() addDs [constrainsD2]) 2); |
280 |
by (Asm_simp_tac 1); |
|
281 |
by (blast_tac (claset() addIs [constrains_weaken]) 1); |
|
282 |
qed "Join_constrains_weaken"; |
|
283 |
||
12195 | 284 |
(*If I=0, it degenerates to SKIP : state co 0, which is false.*) |
285 |
val [major, minor] = Goal |
|
286 |
"[| (!!i. i:I ==> F(i) : A(i) co A'(i)); i: I |] \ |
|
11479 | 287 |
\ ==> (JN i:I. F(i)) : (INT i:I. A(i)) co (UN i:I. A'(i))"; |
12195 | 288 |
by (cut_facts_tac [minor] 1); |
11479 | 289 |
by (asm_simp_tac (simpset() addsimps [JN_constrains]) 1); |
290 |
by (Clarify_tac 1); |
|
12195 | 291 |
by (forw_inst_tac [("i", "x")] major 1); |
292 |
by (forward_tac [constrainsD2] 1); |
|
293 |
by (Asm_full_simp_tac 1); |
|
11479 | 294 |
by (blast_tac (claset() addIs [constrains_weaken]) 1); |
295 |
qed "JN_constrains_weaken"; |
|
296 |
||
12195 | 297 |
Goal "(JN i:I. F(i)): stable(A) <-> ((ALL i:I. programify(F(i)):stable(A)) & st_set(A))"; |
11479 | 298 |
by (asm_simp_tac |
299 |
(simpset() addsimps [stable_def, constrains_def, JOIN_def]) 1); |
|
300 |
by Auto_tac; |
|
12195 | 301 |
by (cut_inst_tac [("F", "F(xa)")] Acts_type 1); |
302 |
by (dres_inst_tac [("x","xb")] bspec 1); |
|
303 |
by Auto_tac; |
|
11479 | 304 |
qed "JN_stable"; |
305 |
||
12195 | 306 |
val [major, minor] = Goalw [initially_def] |
307 |
"[| (!!i. i:I ==>F(i):initially(A)); i:I |] ==> (JN i:I. F(i)):initially(A)"; |
|
308 |
by (cut_facts_tac [minor] 1); |
|
309 |
by (Asm_full_simp_tac 1); |
|
310 |
by Safe_tac; |
|
311 |
by (asm_full_simp_tac (simpset() addsimps [Inter_iff]) 1); |
|
312 |
by (forw_inst_tac [("i", "x")] major 1); |
|
313 |
by Auto_tac; |
|
314 |
qed "initially_JN_I"; |
|
11479 | 315 |
|
12195 | 316 |
val [major, minor] = Goal |
317 |
"[|(!!i. i:I ==> F(i) : invariant(A)); i:I|]==> (JN i:I. F(i)):invariant(A)"; |
|
318 |
by (cut_facts_tac [minor] 1); |
|
319 |
by (auto_tac (claset() addSIs [initially_JN_I] addDs [major], |
|
320 |
simpset() addsimps [invariant_def, JN_stable])); |
|
321 |
by (thin_tac "i:I" 1); |
|
322 |
by (forward_tac [major] 1); |
|
323 |
by (dtac major 2); |
|
324 |
by (auto_tac (claset(), simpset() addsimps [invariant_def])); |
|
325 |
by (ALLGOALS(forward_tac [stableD2])); |
|
326 |
by Auto_tac; |
|
327 |
qed "invariant_JN_I"; |
|
328 |
||
11479 | 329 |
Goal " (F Join G : stable(A)) <-> \ |
330 |
\ (programify(F) : stable(A) & programify(G): stable(A))"; |
|
331 |
by (asm_simp_tac (simpset() addsimps [stable_def]) 1); |
|
332 |
qed "Join_stable"; |
|
12195 | 333 |
AddIffs [Join_stable]; |
11479 | 334 |
|
12195 | 335 |
Goalw [initially_def] "[| F:initially(A); G:initially(A) |] ==> F Join G: initially(A)"; |
336 |
by Auto_tac; |
|
337 |
qed "initially_JoinI"; |
|
338 |
AddSIs [initially_JoinI]; |
|
11479 | 339 |
|
340 |
Goal "[| F : invariant(A); G : invariant(A) |] \ |
|
341 |
\ ==> F Join G : invariant(A)"; |
|
342 |
by (subgoal_tac "F:program&G:program" 1); |
|
343 |
by (blast_tac (claset() addDs [invariantD2]) 2); |
|
344 |
by (full_simp_tac (simpset() addsimps [invariant_def]) 1); |
|
345 |
by (auto_tac (claset() addIs [Join_in_program], simpset())); |
|
346 |
qed "invariant_JoinI"; |
|
347 |
||
348 |
||
349 |
(* Fails if I=0 because INT i:0. A(i) = 0 *) |
|
350 |
Goal "i:I ==> FP(JN i:I. F(i)) = (INT i:I. FP (programify(F(i))))"; |
|
351 |
by (asm_simp_tac (simpset() addsimps [FP_def, Inter_def]) 1); |
|
352 |
by (rtac equalityI 1); |
|
353 |
by Safe_tac; |
|
12195 | 354 |
by (ALLGOALS(subgoal_tac "st_set({x})")); |
11479 | 355 |
by (rotate_tac ~1 3); |
356 |
by (rotate_tac ~1 1); |
|
357 |
by (ALLGOALS(asm_full_simp_tac (simpset() addsimps [JN_stable]))); |
|
12195 | 358 |
by (rewrite_goals_tac [st_set_def]); |
11479 | 359 |
by (REPEAT(Blast_tac 1)); |
360 |
qed "FP_JN"; |
|
361 |
||
362 |
(*** Progress: transient, ensures ***) |
|
363 |
||
364 |
Goal "i:I==>(JN i:I. F(i)) : transient(A) <-> \ |
|
365 |
\ (EX i:I. programify(F(i)) : transient(A))"; |
|
366 |
by (auto_tac (claset(), |
|
367 |
simpset() addsimps [transient_def, JOIN_def])); |
|
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
368 |
by (rewrite_goals_tac [st_set_def]); |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
369 |
by (dres_inst_tac [("x", "xb")] bspec 2); |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
370 |
by (auto_tac (claset() addDs [Acts_type RS subsetD], simpset())); |
11479 | 371 |
qed "JN_transient"; |
372 |
||
373 |
Goal "F Join G : transient(A) <-> \ |
|
374 |
\ (programify(F) : transient(A) | programify(G):transient(A))"; |
|
375 |
by (auto_tac (claset(), |
|
12220 | 376 |
simpset() addsimps [transient_def, Join_def, Int_Un_distrib2])); |
11479 | 377 |
qed "Join_transient"; |
378 |
||
12195 | 379 |
AddIffs [Join_transient]; |
11479 | 380 |
|
381 |
||
382 |
Goal "F : transient(A) ==> F Join G : transient(A)"; |
|
383 |
by (asm_full_simp_tac (simpset() |
|
12195 | 384 |
addsimps [Join_transient, transientD2]) 1); |
11479 | 385 |
qed "Join_transient_I1"; |
386 |
||
387 |
||
388 |
Goal "G : transient(A) ==> F Join G : transient(A)"; |
|
389 |
by (asm_full_simp_tac (simpset() |
|
12195 | 390 |
addsimps [Join_transient, transientD2]) 1); |
11479 | 391 |
qed "Join_transient_I2"; |
392 |
||
393 |
(*If I=0 it degenerates to (SKIP : A ensures B) = False, i.e. to ~(A<=B) *) |
|
394 |
Goal "i : I ==> \ |
|
395 |
\ (JN i:I. F(i)) : A ensures B <-> \ |
|
396 |
\ ((ALL i:I. programify(F(i)) : (A-B) co (A Un B)) & \ |
|
397 |
\ (EX i:I. programify(F(i)) : A ensures B))"; |
|
398 |
by (auto_tac (claset(), |
|
399 |
simpset() addsimps [ensures_def, JN_constrains, JN_transient])); |
|
400 |
qed "JN_ensures"; |
|
401 |
||
402 |
||
403 |
Goalw [ensures_def] |
|
404 |
"F Join G : A ensures B <-> \ |
|
405 |
\ (programify(F) : (A-B) co (A Un B) & programify(G) : (A-B) co (A Un B) & \ |
|
406 |
\ (programify(F): transient (A-B) | programify(G) : transient (A-B)))"; |
|
407 |
by (auto_tac (claset(), simpset() addsimps [Join_transient])); |
|
408 |
qed "Join_ensures"; |
|
409 |
||
12195 | 410 |
Goalw [stable_def, constrains_def, Join_def, st_set_def] |
11479 | 411 |
"[| F : stable(A); G : A co A' |] \ |
412 |
\ ==> F Join G : A co A'"; |
|
12195 | 413 |
by (cut_inst_tac [("F", "F")] Acts_type 1); |
414 |
by (cut_inst_tac [("F", "G")] Acts_type 1); |
|
11479 | 415 |
by Auto_tac; |
12195 | 416 |
by (REPEAT(Blast_tac 1)); |
11479 | 417 |
qed "stable_Join_constrains"; |
418 |
||
419 |
(*Premise for G cannot use Always because F: Stable A is |
|
420 |
weaker than G : stable A *) |
|
421 |
Goal "[| F : stable(A); G : invariant(A) |] ==> F Join G : Always(A)"; |
|
12195 | 422 |
by (subgoal_tac "F:program & G:program & st_set(A)" 1); |
423 |
by (blast_tac (claset() addDs [invariantD2, stableD2]) 2); |
|
424 |
by (asm_full_simp_tac (simpset() addsimps [Always_def, invariant_def,initially_def , |
|
11479 | 425 |
Stable_eq_stable]) 1); |
426 |
by (force_tac(claset() addIs [stable_Int], simpset()) 1); |
|
427 |
qed "stable_Join_Always1"; |
|
428 |
||
429 |
(*As above, but exchanging the roles of F and G*) |
|
430 |
Goal "[| F : invariant(A); G : stable(A) |] ==> F Join G : Always(A)"; |
|
431 |
by (stac Join_commute 1); |
|
432 |
by (blast_tac (claset() addIs [stable_Join_Always1]) 1); |
|
433 |
qed "stable_Join_Always2"; |
|
434 |
||
435 |
||
436 |
||
437 |
Goal "[| F : stable(A); G : A ensures B |] ==> F Join G : A ensures B"; |
|
12195 | 438 |
by (subgoal_tac "F:program & G:program & st_set(A)" 1); |
439 |
by (blast_tac (claset() addDs [stableD2, ensures_type RS subsetD]) 2); |
|
11479 | 440 |
by (asm_simp_tac (simpset() addsimps [Join_ensures]) 1); |
441 |
by (asm_full_simp_tac (simpset() addsimps [stable_def, ensures_def]) 1); |
|
442 |
by (etac constrains_weaken 1); |
|
443 |
by Auto_tac; |
|
444 |
qed "stable_Join_ensures1"; |
|
445 |
||
446 |
||
447 |
(*As above, but exchanging the roles of F and G*) |
|
448 |
Goal "[| F : A ensures B; G : stable(A) |] ==> F Join G : A ensures B"; |
|
449 |
by (stac Join_commute 1); |
|
450 |
by (blast_tac (claset() addIs [stable_Join_ensures1]) 1); |
|
451 |
qed "stable_Join_ensures2"; |
|
452 |
||
12195 | 453 |
(*** The ok and OK relations ***) |
11479 | 454 |
|
455 |
Goal "SKIP ok F"; |
|
12195 | 456 |
by (auto_tac (claset() addDs [Acts_type RS subsetD], simpset() addsimps [ok_def])); |
11479 | 457 |
qed "ok_SKIP1"; |
458 |
||
459 |
Goal "F ok SKIP"; |
|
12195 | 460 |
by (auto_tac (claset() addDs [Acts_type RS subsetD], |
11479 | 461 |
simpset() addsimps [ok_def])); |
462 |
qed "ok_SKIP2"; |
|
463 |
AddIffs [ok_SKIP1, ok_SKIP2]; |
|
464 |
||
465 |
Goal "(F ok G & (F Join G) ok H) <-> (G ok H & F ok (G Join H))"; |
|
466 |
by (auto_tac (claset(), simpset() addsimps [ok_def])); |
|
467 |
qed "ok_Join_commute"; |
|
468 |
||
469 |
Goal "(F ok G) <->(G ok F)"; |
|
470 |
by (auto_tac (claset(), simpset() addsimps [ok_def])); |
|
471 |
qed "ok_commute"; |
|
472 |
||
473 |
bind_thm ("ok_sym", ok_commute RS iffD1); |
|
474 |
||
475 |
Goal "OK({<0,F>,<1,G>,<2,H>}, snd) <-> (F ok G & (F Join G) ok H)"; |
|
476 |
by (asm_full_simp_tac |
|
477 |
(simpset() addsimps [ok_def, Join_def, OK_def, |
|
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
478 |
Int_assoc, cons_absorb, Int_Un_distrib2, Ball_def]) 1); |
11479 | 479 |
by (rtac iffI 1); |
480 |
by Safe_tac; |
|
481 |
by (REPEAT(Force_tac 1)); |
|
482 |
qed "ok_iff_OK"; |
|
483 |
||
484 |
Goal "F ok (G Join H) <-> (F ok G & F ok H)"; |
|
485 |
by (auto_tac (claset(), simpset() addsimps [ok_def])); |
|
486 |
qed "ok_Join_iff1"; |
|
487 |
||
488 |
||
489 |
Goal "(G Join H) ok F <-> (G ok F & H ok F)"; |
|
490 |
by (auto_tac (claset(), simpset() addsimps [ok_def])); |
|
491 |
qed "ok_Join_iff2"; |
|
492 |
AddIffs [ok_Join_iff1, ok_Join_iff2]; |
|
493 |
||
494 |
(*useful? Not with the previous two around*) |
|
495 |
Goal "[| F ok G; (F Join G) ok H |] ==> F ok (G Join H)"; |
|
496 |
by (auto_tac (claset(), simpset() addsimps [ok_def])); |
|
497 |
qed "ok_Join_commute_I"; |
|
498 |
||
499 |
Goal "F ok JOIN(I,G) <-> (ALL i:I. F ok G(i))"; |
|
500 |
by (auto_tac (claset(), simpset() addsimps [ok_def])); |
|
12195 | 501 |
by (blast_tac (claset() addDs [Acts_type RS subsetD]) 1); |
11479 | 502 |
qed "ok_JN_iff1"; |
503 |
||
504 |
||
505 |
Goal "JOIN(I,G) ok F <-> (ALL i:I. G(i) ok F)"; |
|
506 |
by (auto_tac (claset(), simpset() addsimps [ok_def])); |
|
12195 | 507 |
by (blast_tac (claset() addDs [Acts_type RS subsetD]) 1); |
11479 | 508 |
qed "ok_JN_iff2"; |
509 |
AddIffs [ok_JN_iff1, ok_JN_iff2]; |
|
510 |
||
511 |
Goal "OK(I,F) <-> (ALL i: I. ALL j: I-{i}. F(i) ok (F(j)))"; |
|
512 |
by (auto_tac (claset(), simpset() addsimps [ok_def, OK_def])); |
|
513 |
qed "OK_iff_ok"; |
|
514 |
||
515 |
Goal "[| OK(I,F); i: I; j: I; i~=j|] ==> F(i) ok F(j)"; |
|
516 |
by (auto_tac (claset(), simpset() addsimps [OK_iff_ok])); |
|
517 |
qed "OK_imp_ok"; |
|
518 |
||
519 |
||
520 |
(*** Allowed ***) |
|
521 |
||
522 |
Goal "Allowed(SKIP) = program"; |
|
12195 | 523 |
by (auto_tac (claset() addDs [Acts_type RS subsetD], |
11479 | 524 |
simpset() addsimps [Allowed_def])); |
525 |
qed "Allowed_SKIP"; |
|
526 |
||
527 |
Goal "Allowed(F Join G) = \ |
|
528 |
\ Allowed(programify(F)) Int Allowed(programify(G))"; |
|
529 |
by (auto_tac (claset(), simpset() addsimps [Allowed_def])); |
|
530 |
qed "Allowed_Join"; |
|
531 |
||
532 |
Goal "i:I ==> \ |
|
533 |
\ Allowed(JOIN(I,F)) = (INT i:I. Allowed(programify(F(i))))"; |
|
534 |
by (auto_tac (claset(), simpset() addsimps [Allowed_def])); |
|
535 |
qed "Allowed_JN"; |
|
536 |
Addsimps [Allowed_SKIP, Allowed_Join, Allowed_JN]; |
|
537 |
||
538 |
Goal |
|
539 |
"F ok G <-> (programify(F):Allowed(programify(G)) & \ |
|
540 |
\ programify(G):Allowed(programify(F)))"; |
|
541 |
by (asm_simp_tac (simpset() addsimps [ok_def, Allowed_def]) 1); |
|
542 |
qed "ok_iff_Allowed"; |
|
543 |
||
544 |
||
545 |
Goal "OK(I,F) <-> \ |
|
546 |
\ (ALL i: I. ALL j: I-{i}. programify(F(i)) : Allowed(programify(F(j))))"; |
|
547 |
by (auto_tac (claset(), simpset() addsimps [OK_iff_ok, ok_iff_Allowed])); |
|
548 |
qed "OK_iff_Allowed"; |
|
549 |
||
550 |
(*** safety_prop, for reasoning about given instances of "ok" ***) |
|
551 |
||
12195 | 552 |
Goal "safety_prop(X) ==> (Acts(G) <= cons(id(state), (UN F:X. Acts(F)))) <-> (programify(G):X)"; |
11479 | 553 |
by (full_simp_tac( simpset() addsimps [safety_prop_def]) 1); |
554 |
by (Clarify_tac 1); |
|
555 |
by (case_tac "G:program" 1); |
|
556 |
by (ALLGOALS(Asm_full_simp_tac)); |
|
557 |
by (Blast_tac 1); |
|
558 |
by Safe_tac; |
|
559 |
by (Force_tac 2); |
|
560 |
by (force_tac (claset(), simpset() |
|
561 |
addsimps [programify_def]) 1); |
|
562 |
qed "safety_prop_Acts_iff"; |
|
563 |
||
12195 | 564 |
Goal "safety_prop(X) ==> \ |
565 |
\ (UN G:X. Acts(G)) <= AllowedActs(F) <-> (X <= Allowed(programify(F)))"; |
|
11479 | 566 |
by (auto_tac (claset(), |
567 |
simpset() addsimps [Allowed_def, |
|
12195 | 568 |
safety_prop_Acts_iff RS iff_sym])); |
569 |
by (rewrite_goals_tac [safety_prop_def]); |
|
570 |
by Auto_tac; |
|
11479 | 571 |
qed "safety_prop_AllowedActs_iff_Allowed"; |
572 |
||
573 |
||
12195 | 574 |
Goal "safety_prop(X) ==> Allowed(mk_program(init, acts, UN F:X. Acts(F))) = X"; |
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
575 |
by (subgoal_tac "cons(id(state), Union(RepFun(X, Acts)) Int Pow(state * state)) = \ |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
576 |
\ Union(RepFun(X, Acts))" 1); |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
577 |
by (rtac equalityI 2); |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
578 |
by (REPEAT(force_tac (claset() addDs [Acts_type RS subsetD], |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
579 |
simpset() addsimps [safety_prop_def]) 2)); |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
580 |
by (asm_full_simp_tac (simpset() delsimps UN_simps |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
581 |
addsimps [Allowed_def, safety_prop_Acts_iff]) 1); |
12195 | 582 |
by (rewrite_goals_tac [safety_prop_def]); |
11479 | 583 |
by Auto_tac; |
584 |
qed "Allowed_eq"; |
|
585 |
||
586 |
Goal "[| F == mk_program (init, acts, UN F:X. Acts(F)); X:property; safety_prop(X) |] \ |
|
587 |
\ ==> Allowed(F) = X"; |
|
588 |
by (asm_simp_tac (simpset() addsimps [Allowed_eq]) 1); |
|
589 |
qed "def_prg_Allowed"; |
|
590 |
||
591 |
(*For safety_prop to hold, the property must be satisfiable!*) |
|
12195 | 592 |
Goal "safety_prop(A co B) <-> (A <= B & st_set(A))"; |
593 |
by (simp_tac (simpset() addsimps [safety_prop_def, constrains_def, st_set_def]) 1); |
|
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
594 |
by (auto_tac (claset() addDs [Acts_type RS subsetD], simpset())); |
12195 | 595 |
by (REPEAT(Blast_tac 1)); |
11479 | 596 |
qed "safety_prop_constrains"; |
12195 | 597 |
AddIffs [safety_prop_constrains]; |
11479 | 598 |
|
12195 | 599 |
(* To be used with resolution *) |
600 |
Goal "[| A<=B; st_set(A) |] ==>safety_prop(A co B)"; |
|
601 |
by Auto_tac; |
|
602 |
qed "safety_prop_constrainsI"; |
|
11479 | 603 |
|
12195 | 604 |
Goal "safety_prop(stable(A)) <-> st_set(A)"; |
11479 | 605 |
by (asm_simp_tac (simpset() addsimps [stable_def]) 1); |
606 |
qed "safety_prop_stable"; |
|
12195 | 607 |
AddIffs [safety_prop_stable]; |
11479 | 608 |
|
12195 | 609 |
Goal "st_set(A) ==> safety_prop(stable(A))"; |
610 |
by Auto_tac; |
|
611 |
qed "safety_prop_stableI"; |
|
612 |
||
613 |
Goal "[| safety_prop(X) ; safety_prop(Y) |] ==> safety_prop(X Int Y)"; |
|
614 |
by (asm_full_simp_tac (simpset() addsimps [safety_prop_def]) 1); |
|
615 |
by Auto_tac; |
|
11479 | 616 |
by (dres_inst_tac [("B", "Union(RepFun(X Int Y, Acts))"), |
617 |
("C", "Union(RepFun(Y, Acts))")] subset_trans 2); |
|
618 |
by (dres_inst_tac [("B", "Union(RepFun(X Int Y, Acts))"), |
|
619 |
("C", "Union(RepFun(X, Acts))")] subset_trans 1); |
|
620 |
by (REPEAT(Blast_tac 1)); |
|
621 |
qed "safety_prop_Int"; |
|
622 |
Addsimps [safety_prop_Int]; |
|
623 |
||
624 |
(* If I=0 the conclusion becomes safety_prop(0) which is false *) |
|
12195 | 625 |
val [major, minor] = Goalw [safety_prop_def] |
626 |
"[| (!!i. i:I ==>safety_prop(X(i))); i:I |] ==> safety_prop(INT i:I. X(i))"; |
|
627 |
by (cut_facts_tac [minor] 1); |
|
11479 | 628 |
by Safe_tac; |
12195 | 629 |
by (full_simp_tac (simpset() addsimps [Inter_iff]) 1); |
630 |
by (Clarify_tac 1); |
|
631 |
by (forward_tac [major] 1); |
|
632 |
by (dres_inst_tac [("i", "xa")] major 2); |
|
633 |
by (forw_inst_tac [("i", "xa")] major 4); |
|
634 |
by (ALLGOALS(Asm_full_simp_tac)); |
|
635 |
by Auto_tac; |
|
11479 | 636 |
by (dres_inst_tac [("B", "Union(RepFun(Inter(RepFun(I, X)), Acts))"), |
12195 | 637 |
("C", "Union(RepFun(X(xa), Acts))")] subset_trans 1); |
11479 | 638 |
by (REPEAT(Blast_tac 1)); |
12195 | 639 |
qed "safety_prop_Inter"; |
11479 | 640 |
|
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
641 |
Goalw [ok_def] |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
642 |
"[| F == mk_program(init,acts, UN G:X. Acts(G)); safety_prop(X) |] \ |
12195 | 643 |
\ ==> F ok G <-> (programify(G):X & acts Int Pow(state*state) <= AllowedActs(G))"; |
12215
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
644 |
by (dres_inst_tac [("G", "G")] safety_prop_Acts_iff 1); |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
645 |
by Safe_tac; |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
646 |
by (ALLGOALS(cut_inst_tac [("F", "G")] AllowedActs_type)); |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
647 |
by (ALLGOALS(cut_inst_tac [("F", "G")] Acts_type)); |
55c084921240
Modified to make the files build with the new changes in ZF
ehmety
parents:
12195
diff
changeset
|
648 |
by Auto_tac; |
11479 | 649 |
qed "def_UNION_ok_iff"; |
650 |
||
12195 | 651 |