4 Copyright 1998 University of Cambridge |
4 Copyright 1998 University of Cambridge |
5 |
5 |
6 Specification of Chandy and Charpentier's Allocator |
6 Specification of Chandy and Charpentier's Allocator |
7 |
7 |
8 STOP USING o (COMPOSITION), since function application is naturally associative |
8 STOP USING o (COMPOSITION), since function application is naturally associative |
|
9 |
|
10 guarantees_PLam_I looks wrong: refers to lift_prog |
9 *) |
11 *) |
10 |
|
11 |
|
12 Goal "~ f #2 ==> ~ (!t::nat. (#0 <= t & t <= #10) --> f t)"; |
|
13 |
|
14 (*Useful examples: singletonI RS subst_elem, subst_elem RSN (2,IntI) *) |
|
15 Goal "[| b:A; a=b |] ==> a:A"; |
|
16 by (etac ssubst 1); |
|
17 by (assume_tac 1); |
|
18 qed "subst_elem"; |
|
19 |
|
20 |
12 |
21 |
13 |
22 Goal "(ALL i: lessThan n. f i <= g i) --> sum f n <= sum g n"; |
14 Goal "(ALL i: lessThan n. f i <= g i) --> sum f n <= sum g n"; |
23 by (induct_tac "n" 1); |
15 by (induct_tac "n" 1); |
24 by Auto_tac; |
16 by Auto_tac; |
63 AddIffs [inj_sysOfAlloc, surj_sysOfAlloc]; |
55 AddIffs [inj_sysOfAlloc, surj_sysOfAlloc]; |
64 |
56 |
65 Goalw [good_map_def] "good_map sysOfAlloc"; |
57 Goalw [good_map_def] "good_map sysOfAlloc"; |
66 by Auto_tac; |
58 by Auto_tac; |
67 qed "good_map_sysOfAlloc"; |
59 qed "good_map_sysOfAlloc"; |
|
60 Addsimps [good_map_sysOfAlloc]; |
68 |
61 |
69 (*MUST BE AUTOMATED: even the statement of such results*) |
62 (*MUST BE AUTOMATED: even the statement of such results*) |
70 Goal "!!s. inv sysOfAlloc s = \ |
63 Goal "!!s. inv sysOfAlloc s = \ |
71 \ ((| allocGiv = allocGiv s, \ |
64 \ ((| allocGiv = allocGiv s, \ |
72 \ allocAsk = allocAsk s, \ |
65 \ allocAsk = allocAsk s, \ |
74 \ client s)"; |
67 \ client s)"; |
75 by (rtac (inj_sysOfAlloc RS inv_f_eq) 1); |
68 by (rtac (inj_sysOfAlloc RS inv_f_eq) 1); |
76 by (auto_tac (claset() addSWrapper record_split_wrapper, |
69 by (auto_tac (claset() addSWrapper record_split_wrapper, |
77 simpset() addsimps [sysOfAlloc_def])); |
70 simpset() addsimps [sysOfAlloc_def])); |
78 qed "inv_sysOfAlloc_eq"; |
71 qed "inv_sysOfAlloc_eq"; |
79 |
|
80 Addsimps [inv_sysOfAlloc_eq]; |
72 Addsimps [inv_sysOfAlloc_eq]; |
81 |
73 |
82 (**SHOULD NOT BE NECESSARY: The various injections into the system |
74 (**SHOULD NOT BE NECESSARY: The various injections into the system |
83 state need to be treated symmetrically or done automatically*) |
75 state need to be treated symmetrically or done automatically*) |
84 Goalw [sysOfClient_def] "inj sysOfClient"; |
76 Goalw [sysOfClient_def] "inj sysOfClient"; |
97 AddIffs [inj_sysOfClient, surj_sysOfClient]; |
89 AddIffs [inj_sysOfClient, surj_sysOfClient]; |
98 |
90 |
99 Goalw [good_map_def] "good_map sysOfClient"; |
91 Goalw [good_map_def] "good_map sysOfClient"; |
100 by Auto_tac; |
92 by Auto_tac; |
101 qed "good_map_sysOfClient"; |
93 qed "good_map_sysOfClient"; |
|
94 Addsimps [good_map_sysOfClient]; |
102 |
95 |
103 (*MUST BE AUTOMATED: even the statement of such results*) |
96 (*MUST BE AUTOMATED: even the statement of such results*) |
104 Goal "!!s. inv sysOfClient s = \ |
97 Goal "!!s. inv sysOfClient s = \ |
105 \ (client s, \ |
98 \ (client s, \ |
106 \ (| allocGiv = allocGiv s, \ |
99 \ (| allocGiv = allocGiv s, \ |
108 \ allocRel = allocRel s|) )"; |
101 \ allocRel = allocRel s|) )"; |
109 by (rtac (inj_sysOfClient RS inv_f_eq) 1); |
102 by (rtac (inj_sysOfClient RS inv_f_eq) 1); |
110 by (auto_tac (claset() addSWrapper record_split_wrapper, |
103 by (auto_tac (claset() addSWrapper record_split_wrapper, |
111 simpset() addsimps [sysOfAlloc_def, sysOfClient_def])); |
104 simpset() addsimps [sysOfAlloc_def, sysOfClient_def])); |
112 qed "inv_sysOfClient_eq"; |
105 qed "inv_sysOfClient_eq"; |
|
106 Addsimps [inv_sysOfClient_eq]; |
113 |
107 |
114 |
108 |
115 Open_locale "System"; |
109 Open_locale "System"; |
116 |
110 |
117 val Alloc = thm "Alloc"; |
111 val Alloc = thm "Alloc"; |
152 rewrite_rule [network_spec_def, network_ask_def, |
146 rewrite_rule [network_spec_def, network_ask_def, |
153 network_giv_def, network_rel_def] Network; |
147 network_giv_def, network_rel_def] Network; |
154 |
148 |
155 (*CANNOT use bind_thm: it puts the theorem into standard form, in effect |
149 (*CANNOT use bind_thm: it puts the theorem into standard form, in effect |
156 exporting it from the locale*) |
150 exporting it from the locale*) |
157 val Network_Ask = Network_Spec RS IntD1 RS IntD1; |
151 val Network_Ask = Network_Spec RS IntD1 RS IntD1 RS INT_D; |
158 val Network_Giv = Network_Spec RS IntD1 RS IntD2 RS INT_D; |
152 val Network_Giv = Network_Spec RS IntD1 RS IntD2 RS INT_D; |
159 val Network_Rel = Network_Spec RS IntD2 RS INT_D; |
153 val Network_Rel = Network_Spec RS IntD2 RS INT_D; |
160 |
154 |
161 |
155 |
162 (*Alloc : <unfolded specification> *) |
156 (*Alloc : <unfolded specification> *) |
187 qed "Alloc_component_System"; |
181 qed "Alloc_component_System"; |
188 |
182 |
189 AddIffs [Network_component_System, Alloc_component_System]; |
183 AddIffs [Network_component_System, Alloc_component_System]; |
190 |
184 |
191 |
185 |
|
186 fun alloc_export th = good_map_sysOfAlloc RS export th; |
|
187 |
|
188 fun client_export th = good_map_sysOfClient RS export th; |
|
189 |
192 (* F : UNIV guarantees Increasing func |
190 (* F : UNIV guarantees Increasing func |
193 ==> extend sysOfClient F : UNIV guarantees Increasing (func o client) *) |
191 ==> extend sysOfClient F : UNIV guarantees Increasing (func o client) *) |
194 val extend_Client_guar_Increasing = |
192 val extend_Client_guar_Increasing = |
195 good_map_sysOfClient RS export extend_guar_Increasing |
193 client_export extend_guar_Increasing |
196 |> simplify (simpset() addsimps [inv_sysOfClient_eq]); |
194 |> simplify (simpset() addsimps [inv_sysOfClient_eq]); |
197 |
|
198 fun alloc_export th = good_map_sysOfAlloc RS export th; |
|
199 |
195 |
200 (*NEED AUTOMATIC PROPAGATION of Alloc_Increasing*) |
196 (*NEED AUTOMATIC PROPAGATION of Alloc_Increasing*) |
201 Goal "i < Nclients \ |
197 Goal "i < Nclients \ |
202 \ ==> extend sysOfAlloc Alloc : UNIV guarantees Increasing (sub i o allocGiv)"; |
198 \ ==> extend sysOfAlloc Alloc : UNIV guarantees Increasing (sub i o allocGiv)"; |
203 by (dtac (Alloc_Increasing RS alloc_export extend_guar_Increasing) 1); |
199 by (dtac (Alloc_Increasing RS alloc_export extend_guar_Increasing) 1); |
204 by (auto_tac (claset(), simpset() addsimps [o_def])); |
200 by (auto_tac (claset(), simpset() addsimps [o_def])); |
205 qed "extend_Alloc_Increasing_allocGiv"; |
201 qed "extend_Alloc_Increasing_allocGiv"; |
206 |
202 |
207 |
203 |
208 (** Proof of property (1) **) |
204 (*** Proof of the safety property (1) ***) |
209 |
205 |
210 (*step 1*) |
206 (*safety (1), step 1*) |
211 Goalw [System_def] |
207 Goalw [System_def] |
212 "i < Nclients ==> System : Increasing (rel o sub i o client)"; |
208 "i < Nclients ==> System : Increasing (rel o sub i o client)"; |
213 by (rtac ([guaranteesI RS disjI2 RS guarantees_Join_I, UNIV_I] |
209 by (rtac (extend_Client_guar_Increasing RS guarantees_Join_I2 |
214 MRS guaranteesD) 1); |
210 RS guaranteesD) 1); |
215 by (asm_simp_tac |
211 by (rtac (lift_prog_guar_Increasing RS guarantees_PLam_I) 1); |
216 (simpset() addsimps [guarantees_PLam_I, |
212 (*gets Client_Increasing_rel from simpset*) |
217 extend_Client_guar_Increasing RS guaranteesD, |
213 by Auto_tac; |
218 lift_prog_guar_Increasing]) 1); |
|
219 qed "System_Increasing_rel"; |
214 qed "System_Increasing_rel"; |
220 |
215 |
221 (*Note: the first step above performs simple quantifier reasoning. It could |
216 |
222 be replaced by a proof mentioning no guarantees primitives*) |
217 (*safety (1), step 2*) |
223 |
|
224 |
|
225 (*step 2*) |
|
226 Goal "i < Nclients ==> System : Increasing (sub i o allocRel)"; |
218 Goal "i < Nclients ==> System : Increasing (sub i o allocRel)"; |
227 by (rtac Follows_Increasing1 1); |
219 by (rtac Follows_Increasing1 1); |
228 by (blast_tac (claset() addIs [Network_Rel RS component_guaranteesD, |
220 by (blast_tac (claset() addIs [Network_Rel RS component_guaranteesD, |
229 System_Increasing_rel]) 1); |
221 System_Increasing_rel]) 1); |
230 qed "System_Increasing_allocRel"; |
222 qed "System_Increasing_allocRel"; |
231 |
223 |
232 (*step 2*) |
224 (*safety (1), step 3*) |
233 Goal "System : Always {s. sum (%i. (tokens o sub i o allocGiv) s) Nclients \ |
225 Goal "System : Always {s. sum (%i. (tokens o sub i o allocGiv) s) Nclients \ |
234 \ <= NbT + sum (%i. (tokens o sub i o allocRel) s) Nclients}"; |
226 \ <= NbT + sum (%i. (tokens o sub i o allocRel) s) Nclients}"; |
235 by (res_inst_tac |
227 by (res_inst_tac |
236 [("X", "(INT i : lessThan Nclients. Increasing (sub i o allocRel))")] |
228 [("X", "(INT i : lessThan Nclients. Increasing (sub i o allocRel))")] |
237 component_guaranteesD 1); |
229 component_guaranteesD 1); |
248 by (dtac (subset_refl RS alloc_export project_Always_D) 1); |
240 by (dtac (subset_refl RS alloc_export project_Always_D) 1); |
249 by (asm_full_simp_tac |
241 by (asm_full_simp_tac |
250 (simpset() addsimps [alloc_export Collect_eq_extend_set RS sym]) 1); |
242 (simpset() addsimps [alloc_export Collect_eq_extend_set RS sym]) 1); |
251 qed "System_sum_bounded"; |
243 qed "System_sum_bounded"; |
252 |
244 |
253 (*step 3*) |
245 (*safety (1), step 4*) |
254 Goal "System : Always (INT i: lessThan Nclients. \ |
246 Goal "System : Always (INT i: lessThan Nclients. \ |
255 \ {s. (tokens o giv o sub i o client) s \ |
247 \ {s. (tokens o giv o sub i o client) s \ |
256 \ <= (tokens o sub i o allocGiv) s})"; |
248 \ <= (tokens o sub i o allocGiv) s})"; |
257 by (auto_tac (claset(), |
249 by (auto_tac (claset(), |
258 simpset() delsimps [o_apply] |
250 simpset() delsimps [o_apply] |
264 by (blast_tac (claset() addIs [Network_Giv RS component_guaranteesD, |
256 by (blast_tac (claset() addIs [Network_Giv RS component_guaranteesD, |
265 extend_Alloc_Increasing_allocGiv RS component_guaranteesD]) 1); |
257 extend_Alloc_Increasing_allocGiv RS component_guaranteesD]) 1); |
266 qed "System_Always_giv_le_allocGiv"; |
258 qed "System_Always_giv_le_allocGiv"; |
267 |
259 |
268 |
260 |
|
261 (*safety (1), step 5*) |
269 Goal "System : Always (INT i: lessThan Nclients. \ |
262 Goal "System : Always (INT i: lessThan Nclients. \ |
270 \ {s. (tokens o sub i o allocRel) s \ |
263 \ {s. (tokens o sub i o allocRel) s \ |
271 \ <= (tokens o rel o sub i o client) s})"; |
264 \ <= (tokens o rel o sub i o client) s})"; |
272 by (auto_tac (claset(), |
265 by (auto_tac (claset(), |
273 simpset() delsimps [o_apply] |
266 simpset() delsimps [o_apply] |
279 by (blast_tac (claset() addIs [Network_Rel RS component_guaranteesD, |
272 by (blast_tac (claset() addIs [Network_Rel RS component_guaranteesD, |
280 System_Increasing_rel]) 1); |
273 System_Increasing_rel]) 1); |
281 qed "System_Always_allocRel_le_rel"; |
274 qed "System_Always_allocRel_le_rel"; |
282 |
275 |
283 |
276 |
|
277 (*safety (1), step 6*) |
284 Goal "System : Always {s. sum (%i. (tokens o giv o sub i o client)s) Nclients \ |
278 Goal "System : Always {s. sum (%i. (tokens o giv o sub i o client)s) Nclients \ |
285 \ <= NbT + sum (%i. (tokens o rel o sub i o client)s) Nclients}"; |
279 \ <= NbT + sum (%i. (tokens o rel o sub i o client)s) Nclients}"; |
286 by (rtac (Always_Int_rule [System_sum_bounded, System_Always_giv_le_allocGiv, |
280 by (rtac (Always_Int_rule [System_sum_bounded, System_Always_giv_le_allocGiv, |
287 System_Always_allocRel_le_rel] RS Always_weaken) 1); |
281 System_Always_allocRel_le_rel] RS Always_weaken) 1); |
288 by Auto_tac; |
282 by Auto_tac; |
291 by (rtac ([order_refl, sum_mono] MRS add_le_mono) 2); |
285 by (rtac ([order_refl, sum_mono] MRS add_le_mono) 2); |
292 by (assume_tac 3); |
286 by (assume_tac 3); |
293 by Auto_tac; |
287 by Auto_tac; |
294 qed "System_safety"; |
288 qed "System_safety"; |
295 |
289 |
|
290 |
|
291 |
|
292 (*** Proof of the progress property (2) ***) |
|
293 |
|
294 (*we begin with proofs identical to System_Increasing_rel and |
|
295 System_Increasing_allocRel: tactics needed!*) |
|
296 |
|
297 (*progress (2), step 1*) |
|
298 Goalw [System_def] |
|
299 "i < Nclients ==> System : Increasing (ask o sub i o client)"; |
|
300 by (rtac (extend_Client_guar_Increasing RS guarantees_Join_I2 |
|
301 RS guaranteesD) 1); |
|
302 by (rtac (lift_prog_guar_Increasing RS guarantees_PLam_I) 1); |
|
303 by Auto_tac; |
|
304 qed "System_Increasing_ask"; |
|
305 |
|
306 (*progress (2), step 2*) |
|
307 Goal "i < Nclients ==> System : Increasing (sub i o allocAsk)"; |
|
308 by (rtac Follows_Increasing1 1); |
|
309 by (blast_tac (claset() addIs [Network_Ask RS component_guaranteesD, |
|
310 System_Increasing_ask]) 1); |
|
311 qed "System_Increasing_allocAsk"; |
|
312 |
|
313 (*progress (2), step 3*) |
|
314 (*All this trouble just to lift "Client_Bounded" through two extemd ops*) |
|
315 Goalw [System_def] |
|
316 "i < Nclients \ |
|
317 \ ==> System : Always \ |
|
318 \ {s. ALL elt : set ((ask o sub i o client) s). elt <= NbT}"; |
|
319 by (rtac (lift_prog_guar_Always RS |
|
320 guarantees_PLam_I RS client_export extend_guar_Always RS |
|
321 guarantees_Join_I2 RS guaranteesD RS Always_weaken) 1); |
|
322 by (stac Always_UNIV_eq 1 THEN rtac Client_Bounded 1); |
|
323 by (auto_tac(claset(), |
|
324 simpset() addsimps [Collect_eq_lift_set RS sym, |
|
325 client_export Collect_eq_extend_set RS sym])); |
|
326 qed "System_Bounded"; |