48 "strongest_rhs F A == Inter {B. F \<in> A co B}" |
48 "strongest_rhs F A == Inter {B. F \<in> A co B}" |
49 |
49 |
50 invariant :: "'a set => 'a program set" |
50 invariant :: "'a set => 'a program set" |
51 "invariant A == {F. Init F \<subseteq> A} \<inter> stable A" |
51 "invariant A == {F. Init F \<subseteq> A} \<inter> stable A" |
52 |
52 |
53 (*Polymorphic in both states and the meaning of \<le> *) |
|
54 increasing :: "['a => 'b::{order}] => 'a program set" |
53 increasing :: "['a => 'b::{order}] => 'a program set" |
|
54 --{*Polymorphic in both states and the meaning of @{text "\<le>"}*} |
55 "increasing f == \<Inter>z. stable {s. z \<le> f s}" |
55 "increasing f == \<Inter>z. stable {s. z \<le> f s}" |
56 |
56 |
57 |
57 |
58 (*Perhaps equalities.ML shouldn't add this in the first place!*) |
58 text{*Perhaps equalities.ML shouldn't add this in the first place!*} |
59 declare image_Collect [simp del] |
59 declare image_Collect [simp del] |
60 |
60 |
61 (*** The abstract type of programs ***) |
61 (*** The abstract type of programs ***) |
62 |
62 |
63 lemmas program_typedef = |
63 lemmas program_typedef = |
81 by (simp add: insert_absorb Id_in_AllowedActs) |
81 by (simp add: insert_absorb Id_in_AllowedActs) |
82 |
82 |
83 (** Inspectors for type "program" **) |
83 (** Inspectors for type "program" **) |
84 |
84 |
85 lemma Init_eq [simp]: "Init (mk_program (init,acts,allowed)) = init" |
85 lemma Init_eq [simp]: "Init (mk_program (init,acts,allowed)) = init" |
86 by (auto simp add: program_typedef) |
86 by (simp add: program_typedef) |
87 |
87 |
88 lemma Acts_eq [simp]: "Acts (mk_program (init,acts,allowed)) = insert Id acts" |
88 lemma Acts_eq [simp]: "Acts (mk_program (init,acts,allowed)) = insert Id acts" |
89 by (auto simp add: program_typedef) |
89 by (simp add: program_typedef) |
90 |
90 |
91 lemma AllowedActs_eq [simp]: |
91 lemma AllowedActs_eq [simp]: |
92 "AllowedActs (mk_program (init,acts,allowed)) = insert Id allowed" |
92 "AllowedActs (mk_program (init,acts,allowed)) = insert Id allowed" |
93 by (auto simp add: program_typedef) |
93 by (simp add: program_typedef) |
94 |
94 |
95 (** Equality for UNITY programs **) |
95 (** Equality for UNITY programs **) |
96 |
96 |
97 lemma surjective_mk_program [simp]: |
97 lemma surjective_mk_program [simp]: |
98 "mk_program (Init F, Acts F, AllowedActs F) = F" |
98 "mk_program (Init F, Acts F, AllowedActs F) = F" |
119 "(F=G) = |
119 "(F=G) = |
120 (Init F = Init G & Acts F = Acts G &AllowedActs F = AllowedActs G)" |
120 (Init F = Init G & Acts F = Acts G &AllowedActs F = AllowedActs G)" |
121 by (blast intro: program_equalityI program_equalityE) |
121 by (blast intro: program_equalityI program_equalityE) |
122 |
122 |
123 |
123 |
124 (*** These rules allow "lazy" definition expansion |
|
125 They avoid expanding the full program, which is a large expression |
|
126 ***) |
|
127 |
|
128 lemma def_prg_Init: "F == mk_program (init,acts,allowed) ==> Init F = init" |
|
129 by auto |
|
130 |
|
131 lemma def_prg_Acts: |
|
132 "F == mk_program (init,acts,allowed) ==> Acts F = insert Id acts" |
|
133 by auto |
|
134 |
|
135 lemma def_prg_AllowedActs: |
|
136 "F == mk_program (init,acts,allowed) |
|
137 ==> AllowedActs F = insert Id allowed" |
|
138 by auto |
|
139 |
|
140 (*The program is not expanded, but its Init and Acts are*) |
|
141 lemma def_prg_simps: |
|
142 "[| F == mk_program (init,acts,allowed) |] |
|
143 ==> Init F = init & Acts F = insert Id acts" |
|
144 by simp |
|
145 |
|
146 (*An action is expanded only if a pair of states is being tested against it*) |
|
147 lemma def_act_simp: |
|
148 "[| act == {(s,s'). P s s'} |] ==> ((s,s') \<in> act) = P s s'" |
|
149 by auto |
|
150 |
|
151 (*A set is expanded only if an element is being tested against it*) |
|
152 lemma def_set_simp: "A == B ==> (x \<in> A) = (x \<in> B)" |
|
153 by auto |
|
154 |
|
155 |
|
156 (*** co ***) |
124 (*** co ***) |
157 |
125 |
158 lemma constrainsI: |
126 lemma constrainsI: |
159 "(!!act s s'. [| act: Acts F; (s,s') \<in> act; s \<in> A |] ==> s': A') |
127 "(!!act s s'. [| act: Acts F; (s,s') \<in> act; s \<in> A |] ==> s': A') |
160 ==> F \<in> A co A'" |
128 ==> F \<in> A co A'" |
174 by (unfold constrains_def, blast) |
142 by (unfold constrains_def, blast) |
175 |
143 |
176 lemma constrains_UNIV2 [iff]: "F \<in> A co UNIV" |
144 lemma constrains_UNIV2 [iff]: "F \<in> A co UNIV" |
177 by (unfold constrains_def, blast) |
145 by (unfold constrains_def, blast) |
178 |
146 |
179 (*monotonic in 2nd argument*) |
147 text{*monotonic in 2nd argument*} |
180 lemma constrains_weaken_R: |
148 lemma constrains_weaken_R: |
181 "[| F \<in> A co A'; A'<=B' |] ==> F \<in> A co B'" |
149 "[| F \<in> A co A'; A'<=B' |] ==> F \<in> A co B'" |
182 by (unfold constrains_def, blast) |
150 by (unfold constrains_def, blast) |
183 |
151 |
184 (*anti-monotonic in 1st argument*) |
152 text{*anti-monotonic in 1st argument*} |
185 lemma constrains_weaken_L: |
153 lemma constrains_weaken_L: |
186 "[| F \<in> A co A'; B \<subseteq> A |] ==> F \<in> B co A'" |
154 "[| F \<in> A co A'; B \<subseteq> A |] ==> F \<in> B co A'" |
187 by (unfold constrains_def, blast) |
155 by (unfold constrains_def, blast) |
188 |
156 |
189 lemma constrains_weaken: |
157 lemma constrains_weaken: |
225 by (unfold constrains_def, blast) |
193 by (unfold constrains_def, blast) |
226 |
194 |
227 lemma constrains_imp_subset: "F \<in> A co A' ==> A \<subseteq> A'" |
195 lemma constrains_imp_subset: "F \<in> A co A' ==> A \<subseteq> A'" |
228 by (unfold constrains_def, auto) |
196 by (unfold constrains_def, auto) |
229 |
197 |
230 (*The reasoning is by subsets since "co" refers to single actions |
198 text{*The reasoning is by subsets since "co" refers to single actions |
231 only. So this rule isn't that useful.*) |
199 only. So this rule isn't that useful.*} |
232 lemma constrains_trans: |
200 lemma constrains_trans: |
233 "[| F \<in> A co B; F \<in> B co C |] ==> F \<in> A co C" |
201 "[| F \<in> A co B; F \<in> B co C |] ==> F \<in> A co C" |
234 by (unfold constrains_def, blast) |
202 by (unfold constrains_def, blast) |
235 |
203 |
236 lemma constrains_cancel: |
204 lemma constrains_cancel: |
302 (*** invariant ***) |
270 (*** invariant ***) |
303 |
271 |
304 lemma invariantI: "[| Init F \<subseteq> A; F \<in> stable A |] ==> F \<in> invariant A" |
272 lemma invariantI: "[| Init F \<subseteq> A; F \<in> stable A |] ==> F \<in> invariant A" |
305 by (simp add: invariant_def) |
273 by (simp add: invariant_def) |
306 |
274 |
307 (*Could also say "invariant A \<inter> invariant B \<subseteq> invariant (A \<inter> B)"*) |
275 text{*Could also say "invariant A \<inter> invariant B \<subseteq> invariant (A \<inter> B)"*} |
308 lemma invariant_Int: |
276 lemma invariant_Int: |
309 "[| F \<in> invariant A; F \<in> invariant B |] ==> F \<in> invariant (A \<inter> B)" |
277 "[| F \<in> invariant A; F \<in> invariant B |] ==> F \<in> invariant (A \<inter> B)" |
310 by (auto simp add: invariant_def stable_Int) |
278 by (auto simp add: invariant_def stable_Int) |
311 |
279 |
312 |
280 |
313 (*** increasing ***) |
281 (*** increasing ***) |
314 |
282 |
315 lemma increasingD: |
283 lemma increasingD: |
316 "F \<in> increasing f ==> F \<in> stable {s. z \<subseteq> f s}" |
284 "F \<in> increasing f ==> F \<in> stable {s. z \<subseteq> f s}" |
317 |
|
318 by (unfold increasing_def, blast) |
285 by (unfold increasing_def, blast) |
319 |
286 |
320 lemma increasing_constant [iff]: "F \<in> increasing (%s. c)" |
287 lemma increasing_constant [iff]: "F \<in> increasing (%s. c)" |
321 by (unfold increasing_def stable_def, auto) |
288 by (unfold increasing_def stable_def, auto) |
322 |
289 |
339 lemma elimination: |
306 lemma elimination: |
340 "[| \<forall>m \<in> M. F \<in> {s. s x = m} co (B m) |] |
307 "[| \<forall>m \<in> M. F \<in> {s. s x = m} co (B m) |] |
341 ==> F \<in> {s. s x \<in> M} co (\<Union>m \<in> M. B m)" |
308 ==> F \<in> {s. s x \<in> M} co (\<Union>m \<in> M. B m)" |
342 by (unfold constrains_def, blast) |
309 by (unfold constrains_def, blast) |
343 |
310 |
344 (*As above, but for the trivial case of a one-variable state, in which the |
311 text{*As above, but for the trivial case of a one-variable state, in which the |
345 state is identified with its one variable.*) |
312 state is identified with its one variable.*} |
346 lemma elimination_sing: |
313 lemma elimination_sing: |
347 "(\<forall>m \<in> M. F \<in> {m} co (B m)) ==> F \<in> M co (\<Union>m \<in> M. B m)" |
314 "(\<forall>m \<in> M. F \<in> {m} co (B m)) ==> F \<in> M co (\<Union>m \<in> M. B m)" |
348 by (unfold constrains_def, blast) |
315 by (unfold constrains_def, blast) |
349 |
316 |
350 |
317 |
374 by blast |
341 by blast |
375 |
342 |
376 lemma Image_inverse_less_than [simp]: "less_than^-1 `` {k} = lessThan k" |
343 lemma Image_inverse_less_than [simp]: "less_than^-1 `` {k} = lessThan k" |
377 by blast |
344 by blast |
378 |
345 |
|
346 |
|
347 subsection{*Partial versus Total Transitions*} |
|
348 |
|
349 constdefs |
|
350 totalize_act :: "('a * 'a)set => ('a * 'a)set" |
|
351 "totalize_act act == act \<union> diag (-(Domain act))" |
|
352 |
|
353 totalize :: "'a program => 'a program" |
|
354 "totalize F == mk_program (Init F, |
|
355 totalize_act ` Acts F, |
|
356 AllowedActs F)" |
|
357 |
|
358 mk_total_program :: "('a set * ('a * 'a)set set * ('a * 'a)set set) |
|
359 => 'a program" |
|
360 "mk_total_program args == totalize (mk_program args)" |
|
361 |
|
362 all_total :: "'a program => bool" |
|
363 "all_total F == \<forall>act \<in> Acts F. Domain act = UNIV" |
|
364 |
|
365 lemma insert_Id_image_Acts: "f Id = Id ==> insert Id (f`Acts F) = f ` Acts F" |
|
366 by (blast intro: sym [THEN image_eqI]) |
|
367 |
|
368 |
|
369 text{*Basic properties*} |
|
370 |
|
371 lemma totalize_act_Id [simp]: "totalize_act Id = Id" |
|
372 by (simp add: totalize_act_def) |
|
373 |
|
374 lemma Domain_totalize_act [simp]: "Domain (totalize_act act) = UNIV" |
|
375 by (auto simp add: totalize_act_def) |
|
376 |
|
377 lemma Init_totalize [simp]: "Init (totalize F) = Init F" |
|
378 by (unfold totalize_def, auto) |
|
379 |
|
380 lemma Acts_totalize [simp]: "Acts (totalize F) = (totalize_act ` Acts F)" |
|
381 by (simp add: totalize_def insert_Id_image_Acts) |
|
382 |
|
383 lemma AllowedActs_totalize [simp]: "AllowedActs (totalize F) = AllowedActs F" |
|
384 by (simp add: totalize_def) |
|
385 |
|
386 lemma totalize_constrains_iff [simp]: "(totalize F \<in> A co B) = (F \<in> A co B)" |
|
387 by (simp add: totalize_def totalize_act_def constrains_def, blast) |
|
388 |
|
389 lemma totalize_stable_iff [simp]: "(totalize F \<in> stable A) = (F \<in> stable A)" |
|
390 by (simp add: stable_def) |
|
391 |
|
392 lemma totalize_invariant_iff [simp]: |
|
393 "(totalize F \<in> invariant A) = (F \<in> invariant A)" |
|
394 by (simp add: invariant_def) |
|
395 |
|
396 lemma all_total_totalize: "all_total (totalize F)" |
|
397 by (simp add: totalize_def all_total_def) |
|
398 |
|
399 lemma Domain_iff_totalize_act: "(Domain act = UNIV) = (totalize_act act = act)" |
|
400 by (force simp add: totalize_act_def) |
|
401 |
|
402 lemma all_total_imp_totalize: "all_total F ==> (totalize F = F)" |
|
403 apply (simp add: all_total_def totalize_def) |
|
404 apply (rule program_equalityI) |
|
405 apply (simp_all add: Domain_iff_totalize_act image_def) |
|
406 done |
|
407 |
|
408 lemma all_total_iff_totalize: "all_total F = (totalize F = F)" |
|
409 apply (rule iffI) |
|
410 apply (erule all_total_imp_totalize) |
|
411 apply (erule subst) |
|
412 apply (rule all_total_totalize) |
|
413 done |
|
414 |
|
415 lemma mk_total_program_constrains_iff [simp]: |
|
416 "(mk_total_program args \<in> A co B) = (mk_program args \<in> A co B)" |
|
417 by (simp add: mk_total_program_def) |
|
418 |
|
419 |
|
420 subsection{*Rules for Lazy Definition Expansion*} |
|
421 |
|
422 text{*They avoid expanding the full program, which is a large expression*} |
|
423 |
|
424 lemma def_prg_Init: |
|
425 "F == mk_total_program (init,acts,allowed) ==> Init F = init" |
|
426 by (simp add: mk_total_program_def) |
|
427 |
|
428 lemma def_prg_Acts: |
|
429 "F == mk_total_program (init,acts,allowed) |
|
430 ==> Acts F = insert Id (totalize_act ` acts)" |
|
431 by (simp add: mk_total_program_def) |
|
432 |
|
433 lemma def_prg_AllowedActs: |
|
434 "F == mk_total_program (init,acts,allowed) |
|
435 ==> AllowedActs F = insert Id allowed" |
|
436 by (simp add: mk_total_program_def) |
|
437 |
|
438 text{*An action is expanded if a pair of states is being tested against it*} |
|
439 lemma def_act_simp: |
|
440 "act == {(s,s'). P s s'} ==> ((s,s') \<in> act) = P s s'" |
|
441 by (simp add: mk_total_program_def) |
|
442 |
|
443 text{*A set is expanded only if an element is being tested against it*} |
|
444 lemma def_set_simp: "A == B ==> (x \<in> A) = (x \<in> B)" |
|
445 by (simp add: mk_total_program_def) |
|
446 |
|
447 (** Inspectors for type "program" **) |
|
448 |
|
449 lemma Init_total_eq [simp]: |
|
450 "Init (mk_total_program (init,acts,allowed)) = init" |
|
451 by (simp add: mk_total_program_def) |
|
452 |
|
453 lemma Acts_total_eq [simp]: |
|
454 "Acts(mk_total_program(init,acts,allowed)) = insert Id (totalize_act`acts)" |
|
455 by (simp add: mk_total_program_def) |
|
456 |
|
457 lemma AllowedActs_total_eq [simp]: |
|
458 "AllowedActs (mk_total_program (init,acts,allowed)) = insert Id allowed" |
|
459 by (auto simp add: mk_total_program_def) |
|
460 |
379 end |
461 end |