29 "JOIN(I,F) == if I = 0 then SKIP else |
29 "JOIN(I,F) == if I = 0 then SKIP else |
30 mk_program(\<Inter>i \<in> I. Init(F(i)), \<Union>i \<in> I. Acts(F(i)), |
30 mk_program(\<Inter>i \<in> I. Init(F(i)), \<Union>i \<in> I. Acts(F(i)), |
31 \<Inter>i \<in> I. AllowedActs(F(i)))" |
31 \<Inter>i \<in> I. AllowedActs(F(i)))" |
32 |
32 |
33 definition |
33 definition |
34 Join :: "[i, i] => i" (infixl "Join" 65) where |
34 Join :: "[i, i] => i" (infixl "\<squnion>" 65) where |
35 "F Join G == mk_program (Init(F) \<inter> Init(G), Acts(F) \<union> Acts(G), |
35 "F \<squnion> G == mk_program (Init(F) \<inter> Init(G), Acts(F) \<union> Acts(G), |
36 AllowedActs(F) \<inter> AllowedActs(G))" |
36 AllowedActs(F) \<inter> AllowedActs(G))" |
37 definition |
37 definition |
38 (*Characterizes safety properties. Used with specifying AllowedActs*) |
38 (*Characterizes safety properties. Used with specifying AllowedActs*) |
39 safety_prop :: "i => o" where |
39 safety_prop :: "i => o" where |
40 "safety_prop(X) == X\<subseteq>program & |
40 "safety_prop(X) == X\<subseteq>program & |
41 SKIP \<in> X & (\<forall>G \<in> program. Acts(G) \<subseteq> (\<Union>F \<in> X. Acts(F)) \<longrightarrow> G \<in> X)" |
41 SKIP \<in> X & (\<forall>G \<in> program. Acts(G) \<subseteq> (\<Union>F \<in> X. Acts(F)) \<longrightarrow> G \<in> X)" |
42 |
42 |
43 notation (xsymbols) |
|
44 SKIP ("\<bottom>") and |
|
45 Join (infixl "\<squnion>" 65) |
|
46 |
|
47 syntax |
43 syntax |
48 "_JOIN1" :: "[pttrns, i] => i" ("(3JN _./ _)" 10) |
44 "_JOIN1" :: "[pttrns, i] => i" ("(3\<Squnion>_./ _)" 10) |
49 "_JOIN" :: "[pttrn, i, i] => i" ("(3JN _ \<in> _./ _)" 10) |
45 "_JOIN" :: "[pttrn, i, i] => i" ("(3\<Squnion>_ \<in> _./ _)" 10) |
50 syntax (xsymbols) |
|
51 "_JOIN1" :: "[pttrns, i] => i" ("(3\<Squnion> _./ _)" 10) |
|
52 "_JOIN" :: "[pttrn, i, i] => i" ("(3\<Squnion> _ \<in> _./ _)" 10) |
|
53 |
46 |
54 translations |
47 translations |
55 "JN x \<in> A. B" == "CONST JOIN(A, (%x. B))" |
48 "\<Squnion>x \<in> A. B" == "CONST JOIN(A, (\<lambda>x. B))" |
56 "JN x y. B" == "JN x. JN y. B" |
49 "\<Squnion>x y. B" == "\<Squnion>x. \<Squnion>y. B" |
57 "JN x. B" == "CONST JOIN(CONST state,(%x. B))" |
50 "\<Squnion>x. B" == "CONST JOIN(CONST state, (\<lambda>x. B))" |
58 |
51 |
59 |
52 |
60 subsection\<open>SKIP\<close> |
53 subsection\<open>SKIP\<close> |
61 |
54 |
62 lemma reachable_SKIP [simp]: "reachable(SKIP) = state" |
55 lemma reachable_SKIP [simp]: "reachable(SKIP) = state" |
63 by (force elim: reachable.induct intro: reachable.intros) |
56 by (force elim: reachable.induct intro: reachable.intros) |
64 |
57 |
65 text\<open>Elimination programify from ok and Join\<close> |
58 text\<open>Elimination programify from ok and \<squnion>\<close> |
66 |
59 |
67 lemma ok_programify_left [iff]: "programify(F) ok G \<longleftrightarrow> F ok G" |
60 lemma ok_programify_left [iff]: "programify(F) ok G \<longleftrightarrow> F ok G" |
68 by (simp add: ok_def) |
61 by (simp add: ok_def) |
69 |
62 |
70 lemma ok_programify_right [iff]: "F ok programify(G) \<longleftrightarrow> F ok G" |
63 lemma ok_programify_right [iff]: "F ok programify(G) \<longleftrightarrow> F ok G" |
71 by (simp add: ok_def) |
64 by (simp add: ok_def) |
72 |
65 |
73 lemma Join_programify_left [simp]: "programify(F) Join G = F Join G" |
66 lemma Join_programify_left [simp]: "programify(F) \<squnion> G = F \<squnion> G" |
74 by (simp add: Join_def) |
67 by (simp add: Join_def) |
75 |
68 |
76 lemma Join_programify_right [simp]: "F Join programify(G) = F Join G" |
69 lemma Join_programify_right [simp]: "F \<squnion> programify(G) = F \<squnion> G" |
77 by (simp add: Join_def) |
70 by (simp add: Join_def) |
78 |
71 |
79 subsection\<open>SKIP and safety properties\<close> |
72 subsection\<open>SKIP and safety properties\<close> |
80 |
73 |
81 lemma SKIP_in_constrains_iff [iff]: "(SKIP \<in> A co B) \<longleftrightarrow> (A\<subseteq>B & st_set(A))" |
74 lemma SKIP_in_constrains_iff [iff]: "(SKIP \<in> A co B) \<longleftrightarrow> (A\<subseteq>B & st_set(A))" |
90 lemma SKIP_in_Stable [iff]: "SKIP \<in> Stable(A)" |
83 lemma SKIP_in_Stable [iff]: "SKIP \<in> Stable(A)" |
91 by (unfold Stable_def, auto) |
84 by (unfold Stable_def, auto) |
92 |
85 |
93 subsection\<open>Join and JOIN types\<close> |
86 subsection\<open>Join and JOIN types\<close> |
94 |
87 |
95 lemma Join_in_program [iff,TC]: "F Join G \<in> program" |
88 lemma Join_in_program [iff,TC]: "F \<squnion> G \<in> program" |
96 by (unfold Join_def, auto) |
89 by (unfold Join_def, auto) |
97 |
90 |
98 lemma JOIN_in_program [iff,TC]: "JOIN(I,F) \<in> program" |
91 lemma JOIN_in_program [iff,TC]: "JOIN(I,F) \<in> program" |
99 by (unfold JOIN_def, auto) |
92 by (unfold JOIN_def, auto) |
100 |
93 |
101 subsection\<open>Init, Acts, and AllowedActs of Join and JOIN\<close> |
94 subsection\<open>Init, Acts, and AllowedActs of Join and JOIN\<close> |
102 lemma Init_Join [simp]: "Init(F Join G) = Init(F) \<inter> Init(G)" |
95 lemma Init_Join [simp]: "Init(F \<squnion> G) = Init(F) \<inter> Init(G)" |
103 by (simp add: Int_assoc Join_def) |
96 by (simp add: Int_assoc Join_def) |
104 |
97 |
105 lemma Acts_Join [simp]: "Acts(F Join G) = Acts(F) \<union> Acts(G)" |
98 lemma Acts_Join [simp]: "Acts(F \<squnion> G) = Acts(F) \<union> Acts(G)" |
106 by (simp add: Int_Un_distrib2 cons_absorb Join_def) |
99 by (simp add: Int_Un_distrib2 cons_absorb Join_def) |
107 |
100 |
108 lemma AllowedActs_Join [simp]: "AllowedActs(F Join G) = |
101 lemma AllowedActs_Join [simp]: "AllowedActs(F \<squnion> G) = |
109 AllowedActs(F) \<inter> AllowedActs(G)" |
102 AllowedActs(F) \<inter> AllowedActs(G)" |
110 apply (simp add: Int_assoc cons_absorb Join_def) |
103 apply (simp add: Int_assoc cons_absorb Join_def) |
111 done |
104 done |
112 |
105 |
113 subsection\<open>Join's algebraic laws\<close> |
106 subsection\<open>Join's algebraic laws\<close> |
114 |
107 |
115 lemma Join_commute: "F Join G = G Join F" |
108 lemma Join_commute: "F \<squnion> G = G \<squnion> F" |
116 by (simp add: Join_def Un_commute Int_commute) |
109 by (simp add: Join_def Un_commute Int_commute) |
117 |
110 |
118 lemma Join_left_commute: "A Join (B Join C) = B Join (A Join C)" |
111 lemma Join_left_commute: "A \<squnion> (B \<squnion> C) = B \<squnion> (A \<squnion> C)" |
119 apply (simp add: Join_def Int_Un_distrib2 cons_absorb) |
112 apply (simp add: Join_def Int_Un_distrib2 cons_absorb) |
120 apply (simp add: Un_ac Int_ac Int_Un_distrib2 cons_absorb) |
113 apply (simp add: Un_ac Int_ac Int_Un_distrib2 cons_absorb) |
121 done |
114 done |
122 |
115 |
123 lemma Join_assoc: "(F Join G) Join H = F Join (G Join H)" |
116 lemma Join_assoc: "(F \<squnion> G) \<squnion> H = F \<squnion> (G \<squnion> H)" |
124 by (simp add: Un_ac Join_def cons_absorb Int_assoc Int_Un_distrib2) |
117 by (simp add: Un_ac Join_def cons_absorb Int_assoc Int_Un_distrib2) |
125 |
118 |
126 subsection\<open>Needed below\<close> |
119 subsection\<open>Needed below\<close> |
127 lemma cons_id [simp]: "cons(id(state), Pow(state * state)) = Pow(state*state)" |
120 lemma cons_id [simp]: "cons(id(state), Pow(state * state)) = Pow(state*state)" |
128 by auto |
121 by auto |
129 |
122 |
130 lemma Join_SKIP_left [simp]: "SKIP Join F = programify(F)" |
123 lemma Join_SKIP_left [simp]: "SKIP \<squnion> F = programify(F)" |
131 apply (unfold Join_def SKIP_def) |
124 apply (unfold Join_def SKIP_def) |
132 apply (auto simp add: Int_absorb cons_eq) |
125 apply (auto simp add: Int_absorb cons_eq) |
133 done |
126 done |
134 |
127 |
135 lemma Join_SKIP_right [simp]: "F Join SKIP = programify(F)" |
128 lemma Join_SKIP_right [simp]: "F \<squnion> SKIP = programify(F)" |
136 apply (subst Join_commute) |
129 apply (subst Join_commute) |
137 apply (simp add: Join_SKIP_left) |
130 apply (simp add: Join_SKIP_left) |
138 done |
131 done |
139 |
132 |
140 lemma Join_absorb [simp]: "F Join F = programify(F)" |
133 lemma Join_absorb [simp]: "F \<squnion> F = programify(F)" |
141 by (rule program_equalityI, auto) |
134 by (rule program_equalityI, auto) |
142 |
135 |
143 lemma Join_left_absorb: "F Join (F Join G) = F Join G" |
136 lemma Join_left_absorb: "F \<squnion> (F \<squnion> G) = F \<squnion> G" |
144 by (simp add: Join_assoc [symmetric]) |
137 by (simp add: Join_assoc [symmetric]) |
145 |
138 |
146 subsection\<open>Join is an AC-operator\<close> |
139 subsection\<open>Join is an AC-operator\<close> |
147 lemmas Join_ac = Join_assoc Join_left_absorb Join_commute Join_left_commute |
140 lemmas Join_ac = Join_assoc Join_left_absorb Join_commute Join_left_commute |
148 |
141 |
149 subsection\<open>Eliminating programify form JN and OK expressions\<close> |
142 subsection\<open>Eliminating programify form JOIN and OK expressions\<close> |
150 |
143 |
151 lemma OK_programify [iff]: "OK(I, %x. programify(F(x))) \<longleftrightarrow> OK(I, F)" |
144 lemma OK_programify [iff]: "OK(I, %x. programify(F(x))) \<longleftrightarrow> OK(I, F)" |
152 by (simp add: OK_def) |
145 by (simp add: OK_def) |
153 |
146 |
154 lemma JN_programify [iff]: "JOIN(I, %x. programify(F(x))) = JOIN(I, F)" |
147 lemma JOIN_programify [iff]: "JOIN(I, %x. programify(F(x))) = JOIN(I, F)" |
155 by (simp add: JOIN_def) |
148 by (simp add: JOIN_def) |
156 |
149 |
157 |
150 |
158 subsection\<open>JN\<close> |
151 subsection\<open>JOIN\<close> |
159 |
152 |
160 lemma JN_empty [simp]: "JOIN(0, F) = SKIP" |
153 lemma JOIN_empty [simp]: "JOIN(0, F) = SKIP" |
161 by (unfold JOIN_def, auto) |
154 by (unfold JOIN_def, auto) |
162 |
155 |
163 lemma Init_JN [simp]: |
156 lemma Init_JOIN [simp]: |
164 "Init(\<Squnion>i \<in> I. F(i)) = (if I=0 then state else (\<Inter>i \<in> I. Init(F(i))))" |
157 "Init(\<Squnion>i \<in> I. F(i)) = (if I=0 then state else (\<Inter>i \<in> I. Init(F(i))))" |
165 by (simp add: JOIN_def INT_extend_simps del: INT_simps) |
158 by (simp add: JOIN_def INT_extend_simps del: INT_simps) |
166 |
159 |
167 lemma Acts_JN [simp]: |
160 lemma Acts_JOIN [simp]: |
168 "Acts(JOIN(I,F)) = cons(id(state), \<Union>i \<in> I. Acts(F(i)))" |
161 "Acts(JOIN(I,F)) = cons(id(state), \<Union>i \<in> I. Acts(F(i)))" |
169 apply (unfold JOIN_def) |
162 apply (unfold JOIN_def) |
170 apply (auto simp del: INT_simps UN_simps) |
163 apply (auto simp del: INT_simps UN_simps) |
171 apply (rule equalityI) |
164 apply (rule equalityI) |
172 apply (auto dest: Acts_type [THEN subsetD]) |
165 apply (auto dest: Acts_type [THEN subsetD]) |
173 done |
166 done |
174 |
167 |
175 lemma AllowedActs_JN [simp]: |
168 lemma AllowedActs_JOIN [simp]: |
176 "AllowedActs(\<Squnion>i \<in> I. F(i)) = |
169 "AllowedActs(\<Squnion>i \<in> I. F(i)) = |
177 (if I=0 then Pow(state*state) else (\<Inter>i \<in> I. AllowedActs(F(i))))" |
170 (if I=0 then Pow(state*state) else (\<Inter>i \<in> I. AllowedActs(F(i))))" |
178 apply (unfold JOIN_def, auto) |
171 apply (unfold JOIN_def, auto) |
179 apply (rule equalityI) |
172 apply (rule equalityI) |
180 apply (auto elim!: not_emptyE dest: AllowedActs_type [THEN subsetD]) |
173 apply (auto elim!: not_emptyE dest: AllowedActs_type [THEN subsetD]) |
181 done |
174 done |
182 |
175 |
183 lemma JN_cons [simp]: "(\<Squnion>i \<in> cons(a,I). F(i)) = F(a) Join (\<Squnion>i \<in> I. F(i))" |
176 lemma JOIN_cons [simp]: "(\<Squnion>i \<in> cons(a,I). F(i)) = F(a) \<squnion> (\<Squnion>i \<in> I. F(i))" |
184 by (rule program_equalityI, auto) |
177 by (rule program_equalityI, auto) |
185 |
178 |
186 lemma JN_cong [cong]: |
179 lemma JOIN_cong [cong]: |
187 "[| I=J; !!i. i \<in> J ==> F(i) = G(i) |] ==> |
180 "[| I=J; !!i. i \<in> J ==> F(i) = G(i) |] ==> |
188 (\<Squnion>i \<in> I. F(i)) = (\<Squnion>i \<in> J. G(i))" |
181 (\<Squnion>i \<in> I. F(i)) = (\<Squnion>i \<in> J. G(i))" |
189 by (simp add: JOIN_def) |
182 by (simp add: JOIN_def) |
190 |
183 |
191 |
184 |
192 |
185 |
193 subsection\<open>JN laws\<close> |
186 subsection\<open>JOIN laws\<close> |
194 lemma JN_absorb: "k \<in> I ==>F(k) Join (\<Squnion>i \<in> I. F(i)) = (\<Squnion>i \<in> I. F(i))" |
187 lemma JOIN_absorb: "k \<in> I ==>F(k) \<squnion> (\<Squnion>i \<in> I. F(i)) = (\<Squnion>i \<in> I. F(i))" |
195 apply (subst JN_cons [symmetric]) |
188 apply (subst JOIN_cons [symmetric]) |
196 apply (auto simp add: cons_absorb) |
189 apply (auto simp add: cons_absorb) |
197 done |
190 done |
198 |
191 |
199 lemma JN_Un: "(\<Squnion>i \<in> I \<union> J. F(i)) = ((\<Squnion>i \<in> I. F(i)) Join (\<Squnion>i \<in> J. F(i)))" |
192 lemma JOIN_Un: "(\<Squnion>i \<in> I \<union> J. F(i)) = ((\<Squnion>i \<in> I. F(i)) \<squnion> (\<Squnion>i \<in> J. F(i)))" |
200 apply (rule program_equalityI) |
193 apply (rule program_equalityI) |
201 apply (simp_all add: UN_Un INT_Un) |
194 apply (simp_all add: UN_Un INT_Un) |
202 apply (simp_all del: INT_simps add: INT_extend_simps, blast) |
195 apply (simp_all del: INT_simps add: INT_extend_simps, blast) |
203 done |
196 done |
204 |
197 |
205 lemma JN_constant: "(\<Squnion>i \<in> I. c) = (if I=0 then SKIP else programify(c))" |
198 lemma JOIN_constant: "(\<Squnion>i \<in> I. c) = (if I=0 then SKIP else programify(c))" |
206 by (rule program_equalityI, auto) |
199 by (rule program_equalityI, auto) |
207 |
200 |
208 lemma JN_Join_distrib: |
201 lemma JOIN_Join_distrib: |
209 "(\<Squnion>i \<in> I. F(i) Join G(i)) = (\<Squnion>i \<in> I. F(i)) Join (\<Squnion>i \<in> I. G(i))" |
202 "(\<Squnion>i \<in> I. F(i) \<squnion> G(i)) = (\<Squnion>i \<in> I. F(i)) \<squnion> (\<Squnion>i \<in> I. G(i))" |
210 apply (rule program_equalityI) |
203 apply (rule program_equalityI) |
211 apply (simp_all add: INT_Int_distrib, blast) |
204 apply (simp_all add: INT_Int_distrib, blast) |
212 done |
205 done |
213 |
206 |
214 lemma JN_Join_miniscope: "(\<Squnion>i \<in> I. F(i) Join G) = ((\<Squnion>i \<in> I. F(i) Join G))" |
207 lemma JOIN_Join_miniscope: "(\<Squnion>i \<in> I. F(i) \<squnion> G) = ((\<Squnion>i \<in> I. F(i) \<squnion> G))" |
215 by (simp add: JN_Join_distrib JN_constant) |
208 by (simp add: JOIN_Join_distrib JOIN_constant) |
216 |
209 |
217 text\<open>Used to prove guarantees_JN_I\<close> |
210 text\<open>Used to prove guarantees_JOIN_I\<close> |
218 lemma JN_Join_diff: "i \<in> I==>F(i) Join JOIN(I - {i}, F) = JOIN(I, F)" |
211 lemma JOIN_Join_diff: "i \<in> I==>F(i) \<squnion> JOIN(I - {i}, F) = JOIN(I, F)" |
219 apply (rule program_equalityI) |
212 apply (rule program_equalityI) |
220 apply (auto elim!: not_emptyE) |
213 apply (auto elim!: not_emptyE) |
221 done |
214 done |
222 |
215 |
223 subsection\<open>Safety: co, stable, FP\<close> |
216 subsection\<open>Safety: co, stable, FP\<close> |
225 |
218 |
226 (*Fails if I=0 because it collapses to SKIP \<in> A co B, i.e. to A\<subseteq>B. So an |
219 (*Fails if I=0 because it collapses to SKIP \<in> A co B, i.e. to A\<subseteq>B. So an |
227 alternative precondition is A\<subseteq>B, but most proofs using this rule require |
220 alternative precondition is A\<subseteq>B, but most proofs using this rule require |
228 I to be nonempty for other reasons anyway.*) |
221 I to be nonempty for other reasons anyway.*) |
229 |
222 |
230 lemma JN_constrains: |
223 lemma JOIN_constrains: |
231 "i \<in> I==>(\<Squnion>i \<in> I. F(i)) \<in> A co B \<longleftrightarrow> (\<forall>i \<in> I. programify(F(i)) \<in> A co B)" |
224 "i \<in> I==>(\<Squnion>i \<in> I. F(i)) \<in> A co B \<longleftrightarrow> (\<forall>i \<in> I. programify(F(i)) \<in> A co B)" |
232 |
225 |
233 apply (unfold constrains_def JOIN_def st_set_def, auto) |
226 apply (unfold constrains_def JOIN_def st_set_def, auto) |
234 prefer 2 apply blast |
227 prefer 2 apply blast |
235 apply (rename_tac j act y z) |
228 apply (rename_tac j act y z) |
236 apply (cut_tac F = "F (j) " in Acts_type) |
229 apply (cut_tac F = "F (j) " in Acts_type) |
237 apply (drule_tac x = act in bspec, auto) |
230 apply (drule_tac x = act in bspec, auto) |
238 done |
231 done |
239 |
232 |
240 lemma Join_constrains [iff]: |
233 lemma Join_constrains [iff]: |
241 "(F Join G \<in> A co B) \<longleftrightarrow> (programify(F) \<in> A co B & programify(G) \<in> A co B)" |
234 "(F \<squnion> G \<in> A co B) \<longleftrightarrow> (programify(F) \<in> A co B & programify(G) \<in> A co B)" |
242 by (auto simp add: constrains_def) |
235 by (auto simp add: constrains_def) |
243 |
236 |
244 lemma Join_unless [iff]: |
237 lemma Join_unless [iff]: |
245 "(F Join G \<in> A unless B) \<longleftrightarrow> |
238 "(F \<squnion> G \<in> A unless B) \<longleftrightarrow> |
246 (programify(F) \<in> A unless B & programify(G) \<in> A unless B)" |
239 (programify(F) \<in> A unless B & programify(G) \<in> A unless B)" |
247 by (simp add: Join_constrains unless_def) |
240 by (simp add: Join_constrains unless_def) |
248 |
241 |
249 |
242 |
250 (*Analogous weak versions FAIL; see Misra [1994] 5.4.1, Substitution Axiom. |
243 (*Analogous weak versions FAIL; see Misra [1994] 5.4.1, Substitution Axiom. |
251 reachable (F Join G) could be much bigger than reachable F, reachable G |
244 reachable (F \<squnion> G) could be much bigger than reachable F, reachable G |
252 *) |
245 *) |
253 |
246 |
254 lemma Join_constrains_weaken: |
247 lemma Join_constrains_weaken: |
255 "[| F \<in> A co A'; G \<in> B co B' |] |
248 "[| F \<in> A co A'; G \<in> B co B' |] |
256 ==> F Join G \<in> (A \<inter> B) co (A' \<union> B')" |
249 ==> F \<squnion> G \<in> (A \<inter> B) co (A' \<union> B')" |
257 apply (subgoal_tac "st_set (A) & st_set (B) & F \<in> program & G \<in> program") |
250 apply (subgoal_tac "st_set (A) & st_set (B) & F \<in> program & G \<in> program") |
258 prefer 2 apply (blast dest: constrainsD2, simp) |
251 prefer 2 apply (blast dest: constrainsD2, simp) |
259 apply (blast intro: constrains_weaken) |
252 apply (blast intro: constrains_weaken) |
260 done |
253 done |
261 |
254 |
262 (*If I=0, it degenerates to SKIP \<in> state co 0, which is false.*) |
255 (*If I=0, it degenerates to SKIP \<in> state co 0, which is false.*) |
263 lemma JN_constrains_weaken: |
256 lemma JOIN_constrains_weaken: |
264 assumes major: "(!!i. i \<in> I ==> F(i) \<in> A(i) co A'(i))" |
257 assumes major: "(!!i. i \<in> I ==> F(i) \<in> A(i) co A'(i))" |
265 and minor: "i \<in> I" |
258 and minor: "i \<in> I" |
266 shows "(\<Squnion>i \<in> I. F(i)) \<in> (\<Inter>i \<in> I. A(i)) co (\<Union>i \<in> I. A'(i))" |
259 shows "(\<Squnion>i \<in> I. F(i)) \<in> (\<Inter>i \<in> I. A(i)) co (\<Union>i \<in> I. A'(i))" |
267 apply (cut_tac minor) |
260 apply (cut_tac minor) |
268 apply (simp (no_asm_simp) add: JN_constrains) |
261 apply (simp (no_asm_simp) add: JOIN_constrains) |
269 apply clarify |
262 apply clarify |
270 apply (rename_tac "j") |
263 apply (rename_tac "j") |
271 apply (frule_tac i = j in major) |
264 apply (frule_tac i = j in major) |
272 apply (frule constrainsD2, simp) |
265 apply (frule constrainsD2, simp) |
273 apply (blast intro: constrains_weaken) |
266 apply (blast intro: constrains_weaken) |
274 done |
267 done |
275 |
268 |
276 lemma JN_stable: |
269 lemma JOIN_stable: |
277 "(\<Squnion>i \<in> I. F(i)) \<in> stable(A) \<longleftrightarrow> ((\<forall>i \<in> I. programify(F(i)) \<in> stable(A)) & st_set(A))" |
270 "(\<Squnion>i \<in> I. F(i)) \<in> stable(A) \<longleftrightarrow> ((\<forall>i \<in> I. programify(F(i)) \<in> stable(A)) & st_set(A))" |
278 apply (auto simp add: stable_def constrains_def JOIN_def) |
271 apply (auto simp add: stable_def constrains_def JOIN_def) |
279 apply (cut_tac F = "F (i) " in Acts_type) |
272 apply (cut_tac F = "F (i) " in Acts_type) |
280 apply (drule_tac x = act in bspec, auto) |
273 apply (drule_tac x = act in bspec, auto) |
281 done |
274 done |
282 |
275 |
283 lemma initially_JN_I: |
276 lemma initially_JOIN_I: |
284 assumes major: "(!!i. i \<in> I ==>F(i) \<in> initially(A))" |
277 assumes major: "(!!i. i \<in> I ==>F(i) \<in> initially(A))" |
285 and minor: "i \<in> I" |
278 and minor: "i \<in> I" |
286 shows "(\<Squnion>i \<in> I. F(i)) \<in> initially(A)" |
279 shows "(\<Squnion>i \<in> I. F(i)) \<in> initially(A)" |
287 apply (cut_tac minor) |
280 apply (cut_tac minor) |
288 apply (auto elim!: not_emptyE simp add: Inter_iff initially_def) |
281 apply (auto elim!: not_emptyE simp add: Inter_iff initially_def) |
289 apply (frule_tac i = x in major) |
282 apply (frule_tac i = x in major) |
290 apply (auto simp add: initially_def) |
283 apply (auto simp add: initially_def) |
291 done |
284 done |
292 |
285 |
293 lemma invariant_JN_I: |
286 lemma invariant_JOIN_I: |
294 assumes major: "(!!i. i \<in> I ==> F(i) \<in> invariant(A))" |
287 assumes major: "(!!i. i \<in> I ==> F(i) \<in> invariant(A))" |
295 and minor: "i \<in> I" |
288 and minor: "i \<in> I" |
296 shows "(\<Squnion>i \<in> I. F(i)) \<in> invariant(A)" |
289 shows "(\<Squnion>i \<in> I. F(i)) \<in> invariant(A)" |
297 apply (cut_tac minor) |
290 apply (cut_tac minor) |
298 apply (auto intro!: initially_JN_I dest: major simp add: invariant_def JN_stable) |
291 apply (auto intro!: initially_JOIN_I dest: major simp add: invariant_def JOIN_stable) |
299 apply (erule_tac V = "i \<in> I" in thin_rl) |
292 apply (erule_tac V = "i \<in> I" in thin_rl) |
300 apply (frule major) |
293 apply (frule major) |
301 apply (drule_tac [2] major) |
294 apply (drule_tac [2] major) |
302 apply (auto simp add: invariant_def) |
295 apply (auto simp add: invariant_def) |
303 apply (frule stableD2, force)+ |
296 apply (frule stableD2, force)+ |
304 done |
297 done |
305 |
298 |
306 lemma Join_stable [iff]: |
299 lemma Join_stable [iff]: |
307 " (F Join G \<in> stable(A)) \<longleftrightarrow> |
300 " (F \<squnion> G \<in> stable(A)) \<longleftrightarrow> |
308 (programify(F) \<in> stable(A) & programify(G) \<in> stable(A))" |
301 (programify(F) \<in> stable(A) & programify(G) \<in> stable(A))" |
309 by (simp add: stable_def) |
302 by (simp add: stable_def) |
310 |
303 |
311 lemma initially_JoinI [intro!]: |
304 lemma initially_JoinI [intro!]: |
312 "[| F \<in> initially(A); G \<in> initially(A) |] ==> F Join G \<in> initially(A)" |
305 "[| F \<in> initially(A); G \<in> initially(A) |] ==> F \<squnion> G \<in> initially(A)" |
313 by (unfold initially_def, auto) |
306 by (unfold initially_def, auto) |
314 |
307 |
315 lemma invariant_JoinI: |
308 lemma invariant_JoinI: |
316 "[| F \<in> invariant(A); G \<in> invariant(A) |] |
309 "[| F \<in> invariant(A); G \<in> invariant(A) |] |
317 ==> F Join G \<in> invariant(A)" |
310 ==> F \<squnion> G \<in> invariant(A)" |
318 apply (subgoal_tac "F \<in> program&G \<in> program") |
311 apply (subgoal_tac "F \<in> program&G \<in> program") |
319 prefer 2 apply (blast dest: invariantD2) |
312 prefer 2 apply (blast dest: invariantD2) |
320 apply (simp add: invariant_def) |
313 apply (simp add: invariant_def) |
321 apply (auto intro: Join_in_program) |
314 apply (auto intro: Join_in_program) |
322 done |
315 done |
323 |
316 |
324 |
317 |
325 (* Fails if I=0 because \<Inter>i \<in> 0. A(i) = 0 *) |
318 (* Fails if I=0 because \<Inter>i \<in> 0. A(i) = 0 *) |
326 lemma FP_JN: "i \<in> I ==> FP(\<Squnion>i \<in> I. F(i)) = (\<Inter>i \<in> I. FP (programify(F(i))))" |
319 lemma FP_JOIN: "i \<in> I ==> FP(\<Squnion>i \<in> I. F(i)) = (\<Inter>i \<in> I. FP (programify(F(i))))" |
327 by (auto simp add: FP_def Inter_def st_set_def JN_stable) |
320 by (auto simp add: FP_def Inter_def st_set_def JOIN_stable) |
328 |
321 |
329 subsection\<open>Progress: transient, ensures\<close> |
322 subsection\<open>Progress: transient, ensures\<close> |
330 |
323 |
331 lemma JN_transient: |
324 lemma JOIN_transient: |
332 "i \<in> I ==> |
325 "i \<in> I ==> |
333 (\<Squnion>i \<in> I. F(i)) \<in> transient(A) \<longleftrightarrow> (\<exists>i \<in> I. programify(F(i)) \<in> transient(A))" |
326 (\<Squnion>i \<in> I. F(i)) \<in> transient(A) \<longleftrightarrow> (\<exists>i \<in> I. programify(F(i)) \<in> transient(A))" |
334 apply (auto simp add: transient_def JOIN_def) |
327 apply (auto simp add: transient_def JOIN_def) |
335 apply (unfold st_set_def) |
328 apply (unfold st_set_def) |
336 apply (drule_tac [2] x = act in bspec) |
329 apply (drule_tac [2] x = act in bspec) |
337 apply (auto dest: Acts_type [THEN subsetD]) |
330 apply (auto dest: Acts_type [THEN subsetD]) |
338 done |
331 done |
339 |
332 |
340 lemma Join_transient [iff]: |
333 lemma Join_transient [iff]: |
341 "F Join G \<in> transient(A) \<longleftrightarrow> |
334 "F \<squnion> G \<in> transient(A) \<longleftrightarrow> |
342 (programify(F) \<in> transient(A) | programify(G) \<in> transient(A))" |
335 (programify(F) \<in> transient(A) | programify(G) \<in> transient(A))" |
343 apply (auto simp add: transient_def Join_def Int_Un_distrib2) |
336 apply (auto simp add: transient_def Join_def Int_Un_distrib2) |
344 done |
337 done |
345 |
338 |
346 lemma Join_transient_I1: "F \<in> transient(A) ==> F Join G \<in> transient(A)" |
339 lemma Join_transient_I1: "F \<in> transient(A) ==> F \<squnion> G \<in> transient(A)" |
347 by (simp add: Join_transient transientD2) |
340 by (simp add: Join_transient transientD2) |
348 |
341 |
349 |
342 |
350 lemma Join_transient_I2: "G \<in> transient(A) ==> F Join G \<in> transient(A)" |
343 lemma Join_transient_I2: "G \<in> transient(A) ==> F \<squnion> G \<in> transient(A)" |
351 by (simp add: Join_transient transientD2) |
344 by (simp add: Join_transient transientD2) |
352 |
345 |
353 (*If I=0 it degenerates to (SKIP \<in> A ensures B) = False, i.e. to ~(A\<subseteq>B) *) |
346 (*If I=0 it degenerates to (SKIP \<in> A ensures B) = False, i.e. to ~(A\<subseteq>B) *) |
354 lemma JN_ensures: |
347 lemma JOIN_ensures: |
355 "i \<in> I ==> |
348 "i \<in> I ==> |
356 (\<Squnion>i \<in> I. F(i)) \<in> A ensures B \<longleftrightarrow> |
349 (\<Squnion>i \<in> I. F(i)) \<in> A ensures B \<longleftrightarrow> |
357 ((\<forall>i \<in> I. programify(F(i)) \<in> (A-B) co (A \<union> B)) & |
350 ((\<forall>i \<in> I. programify(F(i)) \<in> (A-B) co (A \<union> B)) & |
358 (\<exists>i \<in> I. programify(F(i)) \<in> A ensures B))" |
351 (\<exists>i \<in> I. programify(F(i)) \<in> A ensures B))" |
359 by (auto simp add: ensures_def JN_constrains JN_transient) |
352 by (auto simp add: ensures_def JOIN_constrains JOIN_transient) |
360 |
353 |
361 |
354 |
362 lemma Join_ensures: |
355 lemma Join_ensures: |
363 "F Join G \<in> A ensures B \<longleftrightarrow> |
356 "F \<squnion> G \<in> A ensures B \<longleftrightarrow> |
364 (programify(F) \<in> (A-B) co (A \<union> B) & programify(G) \<in> (A-B) co (A \<union> B) & |
357 (programify(F) \<in> (A-B) co (A \<union> B) & programify(G) \<in> (A-B) co (A \<union> B) & |
365 (programify(F) \<in> transient (A-B) | programify(G) \<in> transient (A-B)))" |
358 (programify(F) \<in> transient (A-B) | programify(G) \<in> transient (A-B)))" |
366 |
359 |
367 apply (unfold ensures_def) |
360 apply (unfold ensures_def) |
368 apply (auto simp add: Join_transient) |
361 apply (auto simp add: Join_transient) |
369 done |
362 done |
370 |
363 |
371 lemma stable_Join_constrains: |
364 lemma stable_Join_constrains: |
372 "[| F \<in> stable(A); G \<in> A co A' |] |
365 "[| F \<in> stable(A); G \<in> A co A' |] |
373 ==> F Join G \<in> A co A'" |
366 ==> F \<squnion> G \<in> A co A'" |
374 apply (unfold stable_def constrains_def Join_def st_set_def) |
367 apply (unfold stable_def constrains_def Join_def st_set_def) |
375 apply (cut_tac F = F in Acts_type) |
368 apply (cut_tac F = F in Acts_type) |
376 apply (cut_tac F = G in Acts_type, force) |
369 apply (cut_tac F = G in Acts_type, force) |
377 done |
370 done |
378 |
371 |
379 (*Premise for G cannot use Always because F \<in> Stable A is |
372 (*Premise for G cannot use Always because F \<in> Stable A is |
380 weaker than G \<in> stable A *) |
373 weaker than G \<in> stable A *) |
381 lemma stable_Join_Always1: |
374 lemma stable_Join_Always1: |
382 "[| F \<in> stable(A); G \<in> invariant(A) |] ==> F Join G \<in> Always(A)" |
375 "[| F \<in> stable(A); G \<in> invariant(A) |] ==> F \<squnion> G \<in> Always(A)" |
383 apply (subgoal_tac "F \<in> program & G \<in> program & st_set (A) ") |
376 apply (subgoal_tac "F \<in> program & G \<in> program & st_set (A) ") |
384 prefer 2 apply (blast dest: invariantD2 stableD2) |
377 prefer 2 apply (blast dest: invariantD2 stableD2) |
385 apply (simp add: Always_def invariant_def initially_def Stable_eq_stable) |
378 apply (simp add: Always_def invariant_def initially_def Stable_eq_stable) |
386 apply (force intro: stable_Int) |
379 apply (force intro: stable_Int) |
387 done |
380 done |
388 |
381 |
389 (*As above, but exchanging the roles of F and G*) |
382 (*As above, but exchanging the roles of F and G*) |
390 lemma stable_Join_Always2: |
383 lemma stable_Join_Always2: |
391 "[| F \<in> invariant(A); G \<in> stable(A) |] ==> F Join G \<in> Always(A)" |
384 "[| F \<in> invariant(A); G \<in> stable(A) |] ==> F \<squnion> G \<in> Always(A)" |
392 apply (subst Join_commute) |
385 apply (subst Join_commute) |
393 apply (blast intro: stable_Join_Always1) |
386 apply (blast intro: stable_Join_Always1) |
394 done |
387 done |
395 |
388 |
396 |
389 |
397 |
390 |
398 lemma stable_Join_ensures1: |
391 lemma stable_Join_ensures1: |
399 "[| F \<in> stable(A); G \<in> A ensures B |] ==> F Join G \<in> A ensures B" |
392 "[| F \<in> stable(A); G \<in> A ensures B |] ==> F \<squnion> G \<in> A ensures B" |
400 apply (subgoal_tac "F \<in> program & G \<in> program & st_set (A) ") |
393 apply (subgoal_tac "F \<in> program & G \<in> program & st_set (A) ") |
401 prefer 2 apply (blast dest: stableD2 ensures_type [THEN subsetD]) |
394 prefer 2 apply (blast dest: stableD2 ensures_type [THEN subsetD]) |
402 apply (simp (no_asm_simp) add: Join_ensures) |
395 apply (simp (no_asm_simp) add: Join_ensures) |
403 apply (simp add: stable_def ensures_def) |
396 apply (simp add: stable_def ensures_def) |
404 apply (erule constrains_weaken, auto) |
397 apply (erule constrains_weaken, auto) |
405 done |
398 done |
406 |
399 |
407 |
400 |
408 (*As above, but exchanging the roles of F and G*) |
401 (*As above, but exchanging the roles of F and G*) |
409 lemma stable_Join_ensures2: |
402 lemma stable_Join_ensures2: |
410 "[| F \<in> A ensures B; G \<in> stable(A) |] ==> F Join G \<in> A ensures B" |
403 "[| F \<in> A ensures B; G \<in> stable(A) |] ==> F \<squnion> G \<in> A ensures B" |
411 apply (subst Join_commute) |
404 apply (subst Join_commute) |
412 apply (blast intro: stable_Join_ensures1) |
405 apply (blast intro: stable_Join_ensures1) |
413 done |
406 done |
414 |
407 |
415 subsection\<open>The ok and OK relations\<close> |
408 subsection\<open>The ok and OK relations\<close> |
419 |
412 |
420 lemma ok_SKIP2 [iff]: "F ok SKIP" |
413 lemma ok_SKIP2 [iff]: "F ok SKIP" |
421 by (auto dest: Acts_type [THEN subsetD] simp add: ok_def) |
414 by (auto dest: Acts_type [THEN subsetD] simp add: ok_def) |
422 |
415 |
423 lemma ok_Join_commute: |
416 lemma ok_Join_commute: |
424 "(F ok G & (F Join G) ok H) \<longleftrightarrow> (G ok H & F ok (G Join H))" |
417 "(F ok G & (F \<squnion> G) ok H) \<longleftrightarrow> (G ok H & F ok (G \<squnion> H))" |
425 by (auto simp add: ok_def) |
418 by (auto simp add: ok_def) |
426 |
419 |
427 lemma ok_commute: "(F ok G) \<longleftrightarrow>(G ok F)" |
420 lemma ok_commute: "(F ok G) \<longleftrightarrow>(G ok F)" |
428 by (auto simp add: ok_def) |
421 by (auto simp add: ok_def) |
429 |
422 |
430 lemmas ok_sym = ok_commute [THEN iffD1] |
423 lemmas ok_sym = ok_commute [THEN iffD1] |
431 |
424 |
432 lemma ok_iff_OK: "OK({<0,F>,<1,G>,<2,H>}, snd) \<longleftrightarrow> (F ok G & (F Join G) ok H)" |
425 lemma ok_iff_OK: "OK({<0,F>,<1,G>,<2,H>}, snd) \<longleftrightarrow> (F ok G & (F \<squnion> G) ok H)" |
433 by (simp add: ok_def Join_def OK_def Int_assoc cons_absorb |
426 by (simp add: ok_def Join_def OK_def Int_assoc cons_absorb |
434 Int_Un_distrib2 Ball_def, safe, force+) |
427 Int_Un_distrib2 Ball_def, safe, force+) |
435 |
428 |
436 lemma ok_Join_iff1 [iff]: "F ok (G Join H) \<longleftrightarrow> (F ok G & F ok H)" |
429 lemma ok_Join_iff1 [iff]: "F ok (G \<squnion> H) \<longleftrightarrow> (F ok G & F ok H)" |
437 by (auto simp add: ok_def) |
430 by (auto simp add: ok_def) |
438 |
431 |
439 lemma ok_Join_iff2 [iff]: "(G Join H) ok F \<longleftrightarrow> (G ok F & H ok F)" |
432 lemma ok_Join_iff2 [iff]: "(G \<squnion> H) ok F \<longleftrightarrow> (G ok F & H ok F)" |
440 by (auto simp add: ok_def) |
433 by (auto simp add: ok_def) |
441 |
434 |
442 (*useful? Not with the previous two around*) |
435 (*useful? Not with the previous two around*) |
443 lemma ok_Join_commute_I: "[| F ok G; (F Join G) ok H |] ==> F ok (G Join H)" |
436 lemma ok_Join_commute_I: "[| F ok G; (F \<squnion> G) ok H |] ==> F ok (G \<squnion> H)" |
444 by (auto simp add: ok_def) |
437 by (auto simp add: ok_def) |
445 |
438 |
446 lemma ok_JN_iff1 [iff]: "F ok JOIN(I,G) \<longleftrightarrow> (\<forall>i \<in> I. F ok G(i))" |
439 lemma ok_JOIN_iff1 [iff]: "F ok JOIN(I,G) \<longleftrightarrow> (\<forall>i \<in> I. F ok G(i))" |
447 by (force dest: Acts_type [THEN subsetD] elim!: not_emptyE simp add: ok_def) |
440 by (force dest: Acts_type [THEN subsetD] elim!: not_emptyE simp add: ok_def) |
448 |
441 |
449 lemma ok_JN_iff2 [iff]: "JOIN(I,G) ok F \<longleftrightarrow> (\<forall>i \<in> I. G(i) ok F)" |
442 lemma ok_JOIN_iff2 [iff]: "JOIN(I,G) ok F \<longleftrightarrow> (\<forall>i \<in> I. G(i) ok F)" |
450 apply (auto elim!: not_emptyE simp add: ok_def) |
443 apply (auto elim!: not_emptyE simp add: ok_def) |
451 apply (blast dest: Acts_type [THEN subsetD]) |
444 apply (blast dest: Acts_type [THEN subsetD]) |
452 done |
445 done |
453 |
446 |
454 lemma OK_iff_ok: "OK(I,F) \<longleftrightarrow> (\<forall>i \<in> I. \<forall>j \<in> I-{i}. F(i) ok (F(j)))" |
447 lemma OK_iff_ok: "OK(I,F) \<longleftrightarrow> (\<forall>i \<in> I. \<forall>j \<in> I-{i}. F(i) ok (F(j)))" |