src/ZF/UNITY/Union.thy
changeset 61392 331be2820f90
parent 60770 240563fbf41d
child 69587 53982d5ec0bb
equal deleted inserted replaced
61391:2332d9be352b 61392:331be2820f90
    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)))"
   473 
   466 
   474 lemma Allowed_SKIP [simp]: "Allowed(SKIP) = program"
   467 lemma Allowed_SKIP [simp]: "Allowed(SKIP) = program"
   475 by (auto dest: Acts_type [THEN subsetD] simp add: Allowed_def)
   468 by (auto dest: Acts_type [THEN subsetD] simp add: Allowed_def)
   476 
   469 
   477 lemma Allowed_Join [simp]:
   470 lemma Allowed_Join [simp]:
   478      "Allowed(F Join G) =
   471      "Allowed(F \<squnion> G) =
   479    Allowed(programify(F)) \<inter> Allowed(programify(G))"
   472    Allowed(programify(F)) \<inter> Allowed(programify(G))"
   480 apply (auto simp add: Allowed_def)
   473 apply (auto simp add: Allowed_def)
   481 done
   474 done
   482 
   475 
   483 lemma Allowed_JN [simp]:
   476 lemma Allowed_JOIN [simp]:
   484      "i \<in> I ==>
   477      "i \<in> I ==>
   485    Allowed(JOIN(I,F)) = (\<Inter>i \<in> I. Allowed(programify(F(i))))"
   478    Allowed(JOIN(I,F)) = (\<Inter>i \<in> I. Allowed(programify(F(i))))"
   486 apply (auto simp add: Allowed_def, blast)
   479 apply (auto simp add: Allowed_def, blast)
   487 done
   480 done
   488 
   481