10 |
10 |
11 theory Union = SubstAx + FP: |
11 theory Union = SubstAx + FP: |
12 |
12 |
13 constdefs |
13 constdefs |
14 |
14 |
15 (*FIXME: conjoin Init F Int Init G ~= {} *) |
15 (*FIXME: conjoin Init F \<inter> Init G \<noteq> {} *) |
16 ok :: "['a program, 'a program] => bool" (infixl "ok" 65) |
16 ok :: "['a program, 'a program] => bool" (infixl "ok" 65) |
17 "F ok G == Acts F <= AllowedActs G & |
17 "F ok G == Acts F \<subseteq> AllowedActs G & |
18 Acts G <= AllowedActs F" |
18 Acts G \<subseteq> AllowedActs F" |
19 |
19 |
20 (*FIXME: conjoin (INT i:I. Init (F i)) ~= {} *) |
20 (*FIXME: conjoin (\<Inter>i \<in> I. Init (F i)) \<noteq> {} *) |
21 OK :: "['a set, 'a => 'b program] => bool" |
21 OK :: "['a set, 'a => 'b program] => bool" |
22 "OK I F == (ALL i:I. ALL j: I-{i}. Acts (F i) <= AllowedActs (F j))" |
22 "OK I F == (\<forall>i \<in> I. \<forall>j \<in> I-{i}. Acts (F i) \<subseteq> AllowedActs (F j))" |
23 |
23 |
24 JOIN :: "['a set, 'a => 'b program] => 'b program" |
24 JOIN :: "['a set, 'a => 'b program] => 'b program" |
25 "JOIN I F == mk_program (INT i:I. Init (F i), UN i:I. Acts (F i), |
25 "JOIN I F == mk_program (\<Inter>i \<in> I. Init (F i), \<Union>i \<in> I. Acts (F i), |
26 INT i:I. AllowedActs (F i))" |
26 \<Inter>i \<in> I. AllowedActs (F i))" |
27 |
27 |
28 Join :: "['a program, 'a program] => 'a program" (infixl "Join" 65) |
28 Join :: "['a program, 'a program] => 'a program" (infixl "Join" 65) |
29 "F Join G == mk_program (Init F Int Init G, Acts F Un Acts G, |
29 "F Join G == mk_program (Init F \<inter> Init G, Acts F \<union> Acts G, |
30 AllowedActs F Int AllowedActs G)" |
30 AllowedActs F \<inter> AllowedActs G)" |
31 |
31 |
32 SKIP :: "'a program" |
32 SKIP :: "'a program" |
33 "SKIP == mk_program (UNIV, {}, UNIV)" |
33 "SKIP == mk_program (UNIV, {}, UNIV)" |
34 |
34 |
35 (*Characterizes safety properties. Used with specifying AllowedActs*) |
35 (*Characterizes safety properties. Used with specifying AllowedActs*) |
36 safety_prop :: "'a program set => bool" |
36 safety_prop :: "'a program set => bool" |
37 "safety_prop X == SKIP: X & (ALL G. Acts G <= UNION X Acts --> G : X)" |
37 "safety_prop X == SKIP: X & (\<forall>G. Acts G \<subseteq> UNION X Acts --> G \<in> X)" |
38 |
38 |
39 syntax |
39 syntax |
40 "@JOIN1" :: "[pttrns, 'b set] => 'b set" ("(3JN _./ _)" 10) |
40 "@JOIN1" :: "[pttrns, 'b set] => 'b set" ("(3JN _./ _)" 10) |
41 "@JOIN" :: "[pttrn, 'a set, 'b set] => 'b set" ("(3JN _:_./ _)" 10) |
41 "@JOIN" :: "[pttrn, 'a set, 'b set] => 'b set" ("(3JN _:_./ _)" 10) |
42 |
42 |
43 translations |
43 translations |
44 "JN x:A. B" == "JOIN A (%x. B)" |
44 "JN x : A. B" == "JOIN A (%x. B)" |
45 "JN x y. B" == "JN x. JN y. B" |
45 "JN x y. B" == "JN x. JN y. B" |
46 "JN x. B" == "JOIN UNIV (%x. B)" |
46 "JN x. B" == "JOIN UNIV (%x. B)" |
47 |
47 |
48 syntax (xsymbols) |
48 syntax (xsymbols) |
49 SKIP :: "'a program" ("\<bottom>") |
49 SKIP :: "'a program" ("\<bottom>") |
50 "op Join" :: "['a program, 'a program] => 'a program" (infixl "\<squnion>" 65) |
50 "op Join" :: "['a program, 'a program] => 'a program" (infixl "\<squnion>" 65) |
51 "@JOIN1" :: "[pttrns, 'b set] => 'b set" ("(3\<Squnion> _./ _)" 10) |
51 "@JOIN1" :: "[pttrns, 'b set] => 'b set" ("(3\<Squnion> _./ _)" 10) |
52 "@JOIN" :: "[pttrn, 'a set, 'b set] => 'b set" ("(3\<Squnion> _:_./ _)" 10) |
52 "@JOIN" :: "[pttrn, 'a set, 'b set] => 'b set" ("(3\<Squnion> _\<in>_./ _)" 10) |
53 |
53 |
54 |
54 |
55 subsection{*SKIP*} |
55 subsection{*SKIP*} |
56 |
56 |
57 lemma Init_SKIP [simp]: "Init SKIP = UNIV" |
57 lemma Init_SKIP [simp]: "Init SKIP = UNIV" |
66 lemma reachable_SKIP [simp]: "reachable SKIP = UNIV" |
66 lemma reachable_SKIP [simp]: "reachable SKIP = UNIV" |
67 by (force elim: reachable.induct intro: reachable.intros) |
67 by (force elim: reachable.induct intro: reachable.intros) |
68 |
68 |
69 subsection{*SKIP and safety properties*} |
69 subsection{*SKIP and safety properties*} |
70 |
70 |
71 lemma SKIP_in_constrains_iff [iff]: "(SKIP : A co B) = (A<=B)" |
71 lemma SKIP_in_constrains_iff [iff]: "(SKIP \<in> A co B) = (A \<subseteq> B)" |
72 by (unfold constrains_def, auto) |
72 by (unfold constrains_def, auto) |
73 |
73 |
74 lemma SKIP_in_Constrains_iff [iff]: "(SKIP : A Co B) = (A<=B)" |
74 lemma SKIP_in_Constrains_iff [iff]: "(SKIP \<in> A Co B) = (A \<subseteq> B)" |
75 by (unfold Constrains_def, auto) |
75 by (unfold Constrains_def, auto) |
76 |
76 |
77 lemma SKIP_in_stable [iff]: "SKIP : stable A" |
77 lemma SKIP_in_stable [iff]: "SKIP \<in> stable A" |
78 by (unfold stable_def, auto) |
78 by (unfold stable_def, auto) |
79 |
79 |
80 declare SKIP_in_stable [THEN stable_imp_Stable, iff] |
80 declare SKIP_in_stable [THEN stable_imp_Stable, iff] |
81 |
81 |
82 |
82 |
83 subsection{*Join*} |
83 subsection{*Join*} |
84 |
84 |
85 lemma Init_Join [simp]: "Init (F Join G) = Init F Int Init G" |
85 lemma Init_Join [simp]: "Init (F Join G) = Init F \<inter> Init G" |
86 by (simp add: Join_def) |
86 by (simp add: Join_def) |
87 |
87 |
88 lemma Acts_Join [simp]: "Acts (F Join G) = Acts F Un Acts G" |
88 lemma Acts_Join [simp]: "Acts (F Join G) = Acts F \<union> Acts G" |
89 by (auto simp add: Join_def) |
89 by (auto simp add: Join_def) |
90 |
90 |
91 lemma AllowedActs_Join [simp]: |
91 lemma AllowedActs_Join [simp]: |
92 "AllowedActs (F Join G) = AllowedActs F Int AllowedActs G" |
92 "AllowedActs (F Join G) = AllowedActs F \<inter> AllowedActs G" |
93 by (auto simp add: Join_def) |
93 by (auto simp add: Join_def) |
94 |
94 |
95 |
95 |
96 subsection{*JN*} |
96 subsection{*JN*} |
97 |
97 |
98 lemma JN_empty [simp]: "(JN i:{}. F i) = SKIP" |
98 lemma JN_empty [simp]: "(\<Squnion>i\<in>{}. F i) = SKIP" |
99 by (unfold JOIN_def SKIP_def, auto) |
99 by (unfold JOIN_def SKIP_def, auto) |
100 |
100 |
101 lemma JN_insert [simp]: "(JN i:insert a I. F i) = (F a) Join (JN i:I. F i)" |
101 lemma JN_insert [simp]: "(\<Squnion>i \<in> insert a I. F i) = (F a) Join (\<Squnion>i \<in> I. F i)" |
102 apply (rule program_equalityI) |
102 apply (rule program_equalityI) |
103 apply (auto simp add: JOIN_def Join_def) |
103 apply (auto simp add: JOIN_def Join_def) |
104 done |
104 done |
105 |
105 |
106 lemma Init_JN [simp]: "Init (JN i:I. F i) = (INT i:I. Init (F i))" |
106 lemma Init_JN [simp]: "Init (\<Squnion>i \<in> I. F i) = (\<Inter>i \<in> I. Init (F i))" |
107 by (simp add: JOIN_def) |
107 by (simp add: JOIN_def) |
108 |
108 |
109 lemma Acts_JN [simp]: "Acts (JN i:I. F i) = insert Id (UN i:I. Acts (F i))" |
109 lemma Acts_JN [simp]: "Acts (\<Squnion>i \<in> I. F i) = insert Id (\<Union>i \<in> I. Acts (F i))" |
110 by (auto simp add: JOIN_def) |
110 by (auto simp add: JOIN_def) |
111 |
111 |
112 lemma AllowedActs_JN [simp]: |
112 lemma AllowedActs_JN [simp]: |
113 "AllowedActs (JN i:I. F i) = (INT i:I. AllowedActs (F i))" |
113 "AllowedActs (\<Squnion>i \<in> I. F i) = (\<Inter>i \<in> I. AllowedActs (F i))" |
114 by (auto simp add: JOIN_def) |
114 by (auto simp add: JOIN_def) |
115 |
115 |
116 |
116 |
117 lemma JN_cong [cong]: |
117 lemma JN_cong [cong]: |
118 "[| I=J; !!i. i:J ==> F i = G i |] ==> (JN i:I. F i) = (JN i:J. G i)" |
118 "[| I=J; !!i. i \<in> J ==> F i = G i |] ==> (\<Squnion>i \<in> I. F i) = (\<Squnion>i \<in> J. G i)" |
119 by (simp add: JOIN_def) |
119 by (simp add: JOIN_def) |
120 |
120 |
121 |
121 |
122 subsection{*Algebraic laws*} |
122 subsection{*Algebraic laws*} |
123 |
123 |
154 |
154 |
155 (*Join is an AC-operator*) |
155 (*Join is an AC-operator*) |
156 lemmas Join_ac = Join_assoc Join_left_absorb Join_commute Join_left_commute |
156 lemmas Join_ac = Join_assoc Join_left_absorb Join_commute Join_left_commute |
157 |
157 |
158 |
158 |
159 subsection{*JN laws*} |
159 subsection{*\<Squnion>laws*} |
160 |
160 |
161 (*Also follows by JN_insert and insert_absorb, but the proof is longer*) |
161 (*Also follows by JN_insert and insert_absorb, but the proof is longer*) |
162 lemma JN_absorb: "k:I ==> F k Join (JN i:I. F i) = (JN i:I. F i)" |
162 lemma JN_absorb: "k \<in> I ==> F k Join (\<Squnion>i \<in> I. F i) = (\<Squnion>i \<in> I. F i)" |
163 by (auto intro!: program_equalityI) |
163 by (auto intro!: program_equalityI) |
164 |
164 |
165 lemma JN_Un: "(JN i: I Un J. F i) = ((JN i: I. F i) Join (JN i:J. F i))" |
165 lemma JN_Un: "(\<Squnion>i \<in> I \<union> J. F i) = ((\<Squnion>i \<in> I. F i) Join (\<Squnion>i \<in> J. F i))" |
166 by (auto intro!: program_equalityI) |
166 by (auto intro!: program_equalityI) |
167 |
167 |
168 lemma JN_constant: "(JN i:I. c) = (if I={} then SKIP else c)" |
168 lemma JN_constant: "(\<Squnion>i \<in> I. c) = (if I={} then SKIP else c)" |
169 by (rule program_equalityI, auto) |
169 by (rule program_equalityI, auto) |
170 |
170 |
171 lemma JN_Join_distrib: |
171 lemma JN_Join_distrib: |
172 "(JN i:I. F i Join G i) = (JN i:I. F i) Join (JN i:I. G i)" |
172 "(\<Squnion>i \<in> I. F i Join G i) = (\<Squnion>i \<in> I. F i) Join (\<Squnion>i \<in> I. G i)" |
173 by (auto intro!: program_equalityI) |
173 by (auto intro!: program_equalityI) |
174 |
174 |
175 lemma JN_Join_miniscope: |
175 lemma JN_Join_miniscope: |
176 "i : I ==> (JN i:I. F i Join G) = ((JN i:I. F i) Join G)" |
176 "i \<in> I ==> (\<Squnion>i \<in> I. F i Join G) = ((\<Squnion>i \<in> I. F i) Join G)" |
177 by (auto simp add: JN_Join_distrib JN_constant) |
177 by (auto simp add: JN_Join_distrib JN_constant) |
178 |
178 |
179 (*Used to prove guarantees_JN_I*) |
179 (*Used to prove guarantees_JN_I*) |
180 lemma JN_Join_diff: "i: I ==> F i Join JOIN (I - {i}) F = JOIN I F" |
180 lemma JN_Join_diff: "i \<in> I ==> F i Join JOIN (I - {i}) F = JOIN I F" |
181 apply (unfold JOIN_def Join_def) |
181 apply (unfold JOIN_def Join_def) |
182 apply (rule program_equalityI, auto) |
182 apply (rule program_equalityI, auto) |
183 done |
183 done |
184 |
184 |
185 |
185 |
186 subsection{*Safety: co, stable, FP*} |
186 subsection{*Safety: co, stable, FP*} |
187 |
187 |
188 (*Fails if I={} because it collapses to SKIP : A co B, i.e. to A<=B. So an |
188 (*Fails if I={} because it collapses to SKIP \<in> A co B, i.e. to A \<subseteq> B. So an |
189 alternative precondition is A<=B, but most proofs using this rule require |
189 alternative precondition is A \<subseteq> B, but most proofs using this rule require |
190 I to be nonempty for other reasons anyway.*) |
190 I to be nonempty for other reasons anyway.*) |
191 lemma JN_constrains: |
191 lemma JN_constrains: |
192 "i : I ==> (JN i:I. F i) : A co B = (ALL i:I. F i : A co B)" |
192 "i \<in> I ==> (\<Squnion>i \<in> I. F i) \<in> A co B = (\<forall>i \<in> I. F i \<in> A co B)" |
193 by (simp add: constrains_def JOIN_def, blast) |
193 by (simp add: constrains_def JOIN_def, blast) |
194 |
194 |
195 lemma Join_constrains [simp]: |
195 lemma Join_constrains [simp]: |
196 "(F Join G : A co B) = (F : A co B & G : A co B)" |
196 "(F Join G \<in> A co B) = (F \<in> A co B & G \<in> A co B)" |
197 by (auto simp add: constrains_def Join_def) |
197 by (auto simp add: constrains_def Join_def) |
198 |
198 |
199 lemma Join_unless [simp]: |
199 lemma Join_unless [simp]: |
200 "(F Join G : A unless B) = (F : A unless B & G : A unless B)" |
200 "(F Join G \<in> A unless B) = (F \<in> A unless B & G \<in> A unless B)" |
201 by (simp add: Join_constrains unless_def) |
201 by (simp add: Join_constrains unless_def) |
202 |
202 |
203 (*Analogous weak versions FAIL; see Misra [1994] 5.4.1, Substitution Axiom. |
203 (*Analogous weak versions FAIL; see Misra [1994] 5.4.1, Substitution Axiom. |
204 reachable (F Join G) could be much bigger than reachable F, reachable G |
204 reachable (F Join G) could be much bigger than reachable F, reachable G |
205 *) |
205 *) |
206 |
206 |
207 |
207 |
208 lemma Join_constrains_weaken: |
208 lemma Join_constrains_weaken: |
209 "[| F : A co A'; G : B co B' |] |
209 "[| F \<in> A co A'; G \<in> B co B' |] |
210 ==> F Join G : (A Int B) co (A' Un B')" |
210 ==> F Join G \<in> (A \<inter> B) co (A' \<union> B')" |
211 by (simp, blast intro: constrains_weaken) |
211 by (simp, blast intro: constrains_weaken) |
212 |
212 |
213 (*If I={}, it degenerates to SKIP : UNIV co {}, which is false.*) |
213 (*If I={}, it degenerates to SKIP \<in> UNIV co {}, which is false.*) |
214 lemma JN_constrains_weaken: |
214 lemma JN_constrains_weaken: |
215 "[| ALL i:I. F i : A i co A' i; i: I |] |
215 "[| \<forall>i \<in> I. F i \<in> A i co A' i; i \<in> I |] |
216 ==> (JN i:I. F i) : (INT i:I. A i) co (UN i:I. A' i)" |
216 ==> (\<Squnion>i \<in> I. F i) \<in> (\<Inter>i \<in> I. A i) co (\<Union>i \<in> I. A' i)" |
217 apply (simp (no_asm_simp) add: JN_constrains) |
217 apply (simp (no_asm_simp) add: JN_constrains) |
218 apply (blast intro: constrains_weaken) |
218 apply (blast intro: constrains_weaken) |
219 done |
219 done |
220 |
220 |
221 lemma JN_stable: "(JN i:I. F i) : stable A = (ALL i:I. F i : stable A)" |
221 lemma JN_stable: "(\<Squnion>i \<in> I. F i) \<in> stable A = (\<forall>i \<in> I. F i \<in> stable A)" |
222 by (simp add: stable_def constrains_def JOIN_def) |
222 by (simp add: stable_def constrains_def JOIN_def) |
223 |
223 |
224 lemma invariant_JN_I: |
224 lemma invariant_JN_I: |
225 "[| !!i. i:I ==> F i : invariant A; i : I |] |
225 "[| !!i. i \<in> I ==> F i \<in> invariant A; i \<in> I |] |
226 ==> (JN i:I. F i) : invariant A" |
226 ==> (\<Squnion>i \<in> I. F i) \<in> invariant A" |
227 by (simp add: invariant_def JN_stable, blast) |
227 by (simp add: invariant_def JN_stable, blast) |
228 |
228 |
229 lemma Join_stable [simp]: |
229 lemma Join_stable [simp]: |
230 "(F Join G : stable A) = |
230 "(F Join G \<in> stable A) = |
231 (F : stable A & G : stable A)" |
231 (F \<in> stable A & G \<in> stable A)" |
232 by (simp add: stable_def) |
232 by (simp add: stable_def) |
233 |
233 |
234 lemma Join_increasing [simp]: |
234 lemma Join_increasing [simp]: |
235 "(F Join G : increasing f) = |
235 "(F Join G \<in> increasing f) = |
236 (F : increasing f & G : increasing f)" |
236 (F \<in> increasing f & G \<in> increasing f)" |
237 by (simp add: increasing_def Join_stable, blast) |
237 by (simp add: increasing_def Join_stable, blast) |
238 |
238 |
239 lemma invariant_JoinI: |
239 lemma invariant_JoinI: |
240 "[| F : invariant A; G : invariant A |] |
240 "[| F \<in> invariant A; G \<in> invariant A |] |
241 ==> F Join G : invariant A" |
241 ==> F Join G \<in> invariant A" |
242 by (simp add: invariant_def, blast) |
242 by (simp add: invariant_def, blast) |
243 |
243 |
244 lemma FP_JN: "FP (JN i:I. F i) = (INT i:I. FP (F i))" |
244 lemma FP_JN: "FP (\<Squnion>i \<in> I. F i) = (\<Inter>i \<in> I. FP (F i))" |
245 by (simp add: FP_def JN_stable INTER_def) |
245 by (simp add: FP_def JN_stable INTER_def) |
246 |
246 |
247 |
247 |
248 subsection{*Progress: transient, ensures*} |
248 subsection{*Progress: transient, ensures*} |
249 |
249 |
250 lemma JN_transient: |
250 lemma JN_transient: |
251 "i : I ==> |
251 "i \<in> I ==> |
252 (JN i:I. F i) : transient A = (EX i:I. F i : transient A)" |
252 (\<Squnion>i \<in> I. F i) \<in> transient A = (\<exists>i \<in> I. F i \<in> transient A)" |
253 by (auto simp add: transient_def JOIN_def) |
253 by (auto simp add: transient_def JOIN_def) |
254 |
254 |
255 lemma Join_transient [simp]: |
255 lemma Join_transient [simp]: |
256 "F Join G : transient A = |
256 "F Join G \<in> transient A = |
257 (F : transient A | G : transient A)" |
257 (F \<in> transient A | G \<in> transient A)" |
258 by (auto simp add: bex_Un transient_def Join_def) |
258 by (auto simp add: bex_Un transient_def Join_def) |
259 |
259 |
260 lemma Join_transient_I1: "F : transient A ==> F Join G : transient A" |
260 lemma Join_transient_I1: "F \<in> transient A ==> F Join G \<in> transient A" |
261 by (simp add: Join_transient) |
261 by (simp add: Join_transient) |
262 |
262 |
263 lemma Join_transient_I2: "G : transient A ==> F Join G : transient A" |
263 lemma Join_transient_I2: "G \<in> transient A ==> F Join G \<in> transient A" |
264 by (simp add: Join_transient) |
264 by (simp add: Join_transient) |
265 |
265 |
266 (*If I={} it degenerates to (SKIP : A ensures B) = False, i.e. to ~(A<=B) *) |
266 (*If I={} it degenerates to (SKIP \<in> A ensures B) = False, i.e. to ~(A \<subseteq> B) *) |
267 lemma JN_ensures: |
267 lemma JN_ensures: |
268 "i : I ==> |
268 "i \<in> I ==> |
269 (JN i:I. F i) : A ensures B = |
269 (\<Squnion>i \<in> I. F i) \<in> A ensures B = |
270 ((ALL i:I. F i : (A-B) co (A Un B)) & (EX i:I. F i : A ensures B))" |
270 ((\<forall>i \<in> I. F i \<in> (A-B) co (A \<union> B)) & (\<exists>i \<in> I. F i \<in> A ensures B))" |
271 by (auto simp add: ensures_def JN_constrains JN_transient) |
271 by (auto simp add: ensures_def JN_constrains JN_transient) |
272 |
272 |
273 lemma Join_ensures: |
273 lemma Join_ensures: |
274 "F Join G : A ensures B = |
274 "F Join G \<in> A ensures B = |
275 (F : (A-B) co (A Un B) & G : (A-B) co (A Un B) & |
275 (F \<in> (A-B) co (A \<union> B) & G \<in> (A-B) co (A \<union> B) & |
276 (F : transient (A-B) | G : transient (A-B)))" |
276 (F \<in> transient (A-B) | G \<in> transient (A-B)))" |
277 by (auto simp add: ensures_def Join_transient) |
277 by (auto simp add: ensures_def Join_transient) |
278 |
278 |
279 lemma stable_Join_constrains: |
279 lemma stable_Join_constrains: |
280 "[| F : stable A; G : A co A' |] |
280 "[| F \<in> stable A; G \<in> A co A' |] |
281 ==> F Join G : A co A'" |
281 ==> F Join G \<in> A co A'" |
282 apply (unfold stable_def constrains_def Join_def) |
282 apply (unfold stable_def constrains_def Join_def) |
283 apply (simp add: ball_Un, blast) |
283 apply (simp add: ball_Un, blast) |
284 done |
284 done |
285 |
285 |
286 (*Premise for G cannot use Always because F: Stable A is weaker than |
286 (*Premise for G cannot use Always because F \<in> Stable A is weaker than |
287 G : stable A *) |
287 G \<in> stable A *) |
288 lemma stable_Join_Always1: |
288 lemma stable_Join_Always1: |
289 "[| F : stable A; G : invariant A |] ==> F Join G : Always A" |
289 "[| F \<in> stable A; G \<in> invariant A |] ==> F Join G \<in> Always A" |
290 apply (simp (no_asm_use) add: Always_def invariant_def Stable_eq_stable) |
290 apply (simp (no_asm_use) add: Always_def invariant_def Stable_eq_stable) |
291 apply (force intro: stable_Int) |
291 apply (force intro: stable_Int) |
292 done |
292 done |
293 |
293 |
294 (*As above, but exchanging the roles of F and G*) |
294 (*As above, but exchanging the roles of F and G*) |
295 lemma stable_Join_Always2: |
295 lemma stable_Join_Always2: |
296 "[| F : invariant A; G : stable A |] ==> F Join G : Always A" |
296 "[| F \<in> invariant A; G \<in> stable A |] ==> F Join G \<in> Always A" |
297 apply (subst Join_commute) |
297 apply (subst Join_commute) |
298 apply (blast intro: stable_Join_Always1) |
298 apply (blast intro: stable_Join_Always1) |
299 done |
299 done |
300 |
300 |
301 lemma stable_Join_ensures1: |
301 lemma stable_Join_ensures1: |
302 "[| F : stable A; G : A ensures B |] ==> F Join G : A ensures B" |
302 "[| F \<in> stable A; G \<in> A ensures B |] ==> F Join G \<in> A ensures B" |
303 apply (simp (no_asm_simp) add: Join_ensures) |
303 apply (simp (no_asm_simp) add: Join_ensures) |
304 apply (simp add: stable_def ensures_def) |
304 apply (simp add: stable_def ensures_def) |
305 apply (erule constrains_weaken, auto) |
305 apply (erule constrains_weaken, auto) |
306 done |
306 done |
307 |
307 |
308 (*As above, but exchanging the roles of F and G*) |
308 (*As above, but exchanging the roles of F and G*) |
309 lemma stable_Join_ensures2: |
309 lemma stable_Join_ensures2: |
310 "[| F : A ensures B; G : stable A |] ==> F Join G : A ensures B" |
310 "[| F \<in> A ensures B; G \<in> stable A |] ==> F Join G \<in> A ensures B" |
311 apply (subst Join_commute) |
311 apply (subst Join_commute) |
312 apply (blast intro: stable_Join_ensures1) |
312 apply (blast intro: stable_Join_ensures1) |
313 done |
313 done |
314 |
314 |
315 |
315 |
342 |
342 |
343 (*useful? Not with the previous two around*) |
343 (*useful? Not with the previous two around*) |
344 lemma ok_Join_commute_I: "[| F ok G; (F Join G) ok H |] ==> F ok (G Join H)" |
344 lemma ok_Join_commute_I: "[| F ok G; (F Join G) ok H |] ==> F ok (G Join H)" |
345 by (auto simp add: ok_def) |
345 by (auto simp add: ok_def) |
346 |
346 |
347 lemma ok_JN_iff1 [iff]: "F ok (JOIN I G) = (ALL i:I. F ok G i)" |
347 lemma ok_JN_iff1 [iff]: "F ok (JOIN I G) = (\<forall>i \<in> I. F ok G i)" |
348 by (auto simp add: ok_def) |
348 by (auto simp add: ok_def) |
349 |
349 |
350 lemma ok_JN_iff2 [iff]: "(JOIN I G) ok F = (ALL i:I. G i ok F)" |
350 lemma ok_JN_iff2 [iff]: "(JOIN I G) ok F = (\<forall>i \<in> I. G i ok F)" |
351 by (auto simp add: ok_def) |
351 by (auto simp add: ok_def) |
352 |
352 |
353 lemma OK_iff_ok: "OK I F = (ALL i: I. ALL j: I-{i}. (F i) ok (F j))" |
353 lemma OK_iff_ok: "OK I F = (\<forall>i \<in> I. \<forall>j \<in> I-{i}. (F i) ok (F j))" |
354 by (auto simp add: ok_def OK_def) |
354 by (auto simp add: ok_def OK_def) |
355 |
355 |
356 lemma OK_imp_ok: "[| OK I F; i: I; j: I; i ~= j|] ==> (F i) ok (F j)" |
356 lemma OK_imp_ok: "[| OK I F; i \<in> I; j \<in> I; i \<noteq> j|] ==> (F i) ok (F j)" |
357 by (auto simp add: OK_iff_ok) |
357 by (auto simp add: OK_iff_ok) |
358 |
358 |
359 |
359 |
360 subsection{*Allowed*} |
360 subsection{*Allowed*} |
361 |
361 |
362 lemma Allowed_SKIP [simp]: "Allowed SKIP = UNIV" |
362 lemma Allowed_SKIP [simp]: "Allowed SKIP = UNIV" |
363 by (auto simp add: Allowed_def) |
363 by (auto simp add: Allowed_def) |
364 |
364 |
365 lemma Allowed_Join [simp]: "Allowed (F Join G) = Allowed F Int Allowed G" |
365 lemma Allowed_Join [simp]: "Allowed (F Join G) = Allowed F \<inter> Allowed G" |
366 by (auto simp add: Allowed_def) |
366 by (auto simp add: Allowed_def) |
367 |
367 |
368 lemma Allowed_JN [simp]: "Allowed (JOIN I F) = (INT i:I. Allowed (F i))" |
368 lemma Allowed_JN [simp]: "Allowed (JOIN I F) = (\<Inter>i \<in> I. Allowed (F i))" |
369 by (auto simp add: Allowed_def) |
369 by (auto simp add: Allowed_def) |
370 |
370 |
371 lemma ok_iff_Allowed: "F ok G = (F : Allowed G & G : Allowed F)" |
371 lemma ok_iff_Allowed: "F ok G = (F \<in> Allowed G & G \<in> Allowed F)" |
372 by (simp add: ok_def Allowed_def) |
372 by (simp add: ok_def Allowed_def) |
373 |
373 |
374 lemma OK_iff_Allowed: "OK I F = (ALL i: I. ALL j: I-{i}. F i : Allowed(F j))" |
374 lemma OK_iff_Allowed: "OK I F = (\<forall>i \<in> I. \<forall>j \<in> I-{i}. F i \<in> Allowed(F j))" |
375 by (auto simp add: OK_iff_ok ok_iff_Allowed) |
375 by (auto simp add: OK_iff_ok ok_iff_Allowed) |
376 |
376 |
377 subsection{*@{text safety_prop}, for reasoning about |
377 subsection{*@{text safety_prop}, for reasoning about |
378 given instances of "ok"*} |
378 given instances of "ok"*} |
379 |
379 |
380 lemma safety_prop_Acts_iff: |
380 lemma safety_prop_Acts_iff: |
381 "safety_prop X ==> (Acts G <= insert Id (UNION X Acts)) = (G : X)" |
381 "safety_prop X ==> (Acts G \<subseteq> insert Id (UNION X Acts)) = (G \<in> X)" |
382 by (auto simp add: safety_prop_def) |
382 by (auto simp add: safety_prop_def) |
383 |
383 |
384 lemma safety_prop_AllowedActs_iff_Allowed: |
384 lemma safety_prop_AllowedActs_iff_Allowed: |
385 "safety_prop X ==> (UNION X Acts <= AllowedActs F) = (X <= Allowed F)" |
385 "safety_prop X ==> (UNION X Acts \<subseteq> AllowedActs F) = (X \<subseteq> Allowed F)" |
386 by (auto simp add: Allowed_def safety_prop_Acts_iff [symmetric]) |
386 by (auto simp add: Allowed_def safety_prop_Acts_iff [symmetric]) |
387 |
387 |
388 lemma Allowed_eq: |
388 lemma Allowed_eq: |
389 "safety_prop X ==> Allowed (mk_program (init, acts, UNION X Acts)) = X" |
389 "safety_prop X ==> Allowed (mk_program (init, acts, UNION X Acts)) = X" |
390 by (simp add: Allowed_def safety_prop_Acts_iff) |
390 by (simp add: Allowed_def safety_prop_Acts_iff) |
393 "[| F == mk_program (init, acts, UNION X Acts) ; safety_prop X |] |
393 "[| F == mk_program (init, acts, UNION X Acts) ; safety_prop X |] |
394 ==> Allowed F = X" |
394 ==> Allowed F = X" |
395 by (simp add: Allowed_eq) |
395 by (simp add: Allowed_eq) |
396 |
396 |
397 (*For safety_prop to hold, the property must be satisfiable!*) |
397 (*For safety_prop to hold, the property must be satisfiable!*) |
398 lemma safety_prop_constrains [iff]: "safety_prop (A co B) = (A <= B)" |
398 lemma safety_prop_constrains [iff]: "safety_prop (A co B) = (A \<subseteq> B)" |
399 by (simp add: safety_prop_def constrains_def, blast) |
399 by (simp add: safety_prop_def constrains_def, blast) |
400 |
400 |
401 lemma safety_prop_stable [iff]: "safety_prop (stable A)" |
401 lemma safety_prop_stable [iff]: "safety_prop (stable A)" |
402 by (simp add: stable_def) |
402 by (simp add: stable_def) |
403 |
403 |
404 lemma safety_prop_Int [simp]: |
404 lemma safety_prop_Int [simp]: |
405 "[| safety_prop X; safety_prop Y |] ==> safety_prop (X Int Y)" |
405 "[| safety_prop X; safety_prop Y |] ==> safety_prop (X \<inter> Y)" |
406 by (simp add: safety_prop_def, blast) |
406 by (simp add: safety_prop_def, blast) |
407 |
407 |
408 lemma safety_prop_INTER1 [simp]: |
408 lemma safety_prop_INTER1 [simp]: |
409 "(!!i. safety_prop (X i)) ==> safety_prop (INT i. X i)" |
409 "(!!i. safety_prop (X i)) ==> safety_prop (\<Inter>i. X i)" |
410 by (auto simp add: safety_prop_def, blast) |
410 by (auto simp add: safety_prop_def, blast) |
411 |
411 |
412 lemma safety_prop_INTER [simp]: |
412 lemma safety_prop_INTER [simp]: |
413 "(!!i. i:I ==> safety_prop (X i)) ==> safety_prop (INT i:I. X i)" |
413 "(!!i. i \<in> I ==> safety_prop (X i)) ==> safety_prop (\<Inter>i \<in> I. X i)" |
414 by (auto simp add: safety_prop_def, blast) |
414 by (auto simp add: safety_prop_def, blast) |
415 |
415 |
416 lemma def_UNION_ok_iff: |
416 lemma def_UNION_ok_iff: |
417 "[| F == mk_program(init,acts,UNION X Acts); safety_prop X |] |
417 "[| F == mk_program(init,acts,UNION X Acts); safety_prop X |] |
418 ==> F ok G = (G : X & acts <= AllowedActs G)" |
418 ==> F ok G = (G \<in> X & acts \<subseteq> AllowedActs G)" |
419 by (auto simp add: ok_def safety_prop_Acts_iff) |
419 by (auto simp add: ok_def safety_prop_Acts_iff) |
420 |
420 |
421 end |
421 end |