src/ZF/UNITY/WFair.thy
changeset 46823 57bf0cecb366
parent 45602 2a858377c3d2
child 46953 2b6e55924af3
equal deleted inserted replaced
46822:95f1e700b712 46823:57bf0cecb366
    15 
    15 
    16 definition
    16 definition
    17   (* This definition specifies weak fairness.  The rest of the theory
    17   (* This definition specifies weak fairness.  The rest of the theory
    18     is generic to all forms of fairness.*) 
    18     is generic to all forms of fairness.*) 
    19   transient :: "i=>i"  where
    19   transient :: "i=>i"  where
    20   "transient(A) =={F:program. (EX act: Acts(F). A<=domain(act) &
    20   "transient(A) =={F:program. (\<exists>act\<in>Acts(F). A<=domain(act) &
    21                                act``A <= state-A) & st_set(A)}"
    21                                act``A \<subseteq> state-A) & st_set(A)}"
    22 
    22 
    23 definition
    23 definition
    24   ensures :: "[i,i] => i"       (infixl "ensures" 60)  where
    24   ensures :: "[i,i] => i"       (infixl "ensures" 60)  where
    25   "A ensures B == ((A-B) co (A Un B)) Int transient(A-B)"
    25   "A ensures B == ((A-B) co (A \<union> B)) \<inter> transient(A-B)"
    26   
    26   
    27 consts
    27 consts
    28 
    28 
    29   (*LEADS-TO constant for the inductive definition*)
    29   (*LEADS-TO constant for the inductive definition*)
    30   leads :: "[i, i]=>i"
    30   leads :: "[i, i]=>i"
    31 
    31 
    32 inductive 
    32 inductive 
    33   domains
    33   domains
    34      "leads(D, F)" <= "Pow(D)*Pow(D)"
    34      "leads(D, F)" \<subseteq> "Pow(D)*Pow(D)"
    35   intros 
    35   intros 
    36     Basis:  "[| F:A ensures B;  A:Pow(D); B:Pow(D) |] ==> <A,B>:leads(D, F)"
    36     Basis:  "[| F:A ensures B;  A:Pow(D); B:Pow(D) |] ==> <A,B>:leads(D, F)"
    37     Trans:  "[| <A,B> : leads(D, F); <B,C> : leads(D, F) |] ==>  <A,C>:leads(D, F)"
    37     Trans:  "[| <A,B> \<in> leads(D, F); <B,C> \<in> leads(D, F) |] ==>  <A,C>:leads(D, F)"
    38     Union:   "[| S:Pow({A:S. <A, B>:leads(D, F)}); B:Pow(D); S:Pow(Pow(D)) |] ==> 
    38     Union:   "[| S:Pow({A:S. <A, B>:leads(D, F)}); B:Pow(D); S:Pow(Pow(D)) |] ==> 
    39               <Union(S),B>:leads(D, F)"
    39               <\<Union>(S),B>:leads(D, F)"
    40 
    40 
    41   monos        Pow_mono
    41   monos        Pow_mono
    42   type_intros  Union_Pow_iff [THEN iffD2] UnionI PowI
    42   type_intros  Union_Pow_iff [THEN iffD2] UnionI PowI
    43  
    43  
    44 definition
    44 definition
    47   "A leadsTo B == {F:program. <A,B>:leads(state, F)}"
    47   "A leadsTo B == {F:program. <A,B>:leads(state, F)}"
    48   
    48   
    49 definition
    49 definition
    50   (* wlt(F, B) is the largest set that leads to B*)
    50   (* wlt(F, B) is the largest set that leads to B*)
    51   wlt :: "[i, i] => i"  where
    51   wlt :: "[i, i] => i"  where
    52     "wlt(F, B) == Union({A:Pow(state). F: A leadsTo B})"
    52     "wlt(F, B) == \<Union>({A:Pow(state). F: A leadsTo B})"
    53 
    53 
    54 notation (xsymbols)
    54 notation (xsymbols)
    55   leadsTo  (infixl "\<longmapsto>" 60)
    55   leadsTo  (infixl "\<longmapsto>" 60)
    56 
    56 
    57 (** Ad-hoc set-theory rules **)
    57 (** Ad-hoc set-theory rules **)
    58 
    58 
    59 lemma Int_Union_Union: "Union(B) Int A = (\<Union>b \<in> B. b Int A)"
    59 lemma Int_Union_Union: "\<Union>(B) \<inter> A = (\<Union>b \<in> B. b \<inter> A)"
    60 by auto
    60 by auto
    61 
    61 
    62 lemma Int_Union_Union2: "A Int Union(B) = (\<Union>b \<in> B. A Int b)"
    62 lemma Int_Union_Union2: "A \<inter> \<Union>(B) = (\<Union>b \<in> B. A \<inter> b)"
    63 by auto
    63 by auto
    64 
    64 
    65 (*** transient ***)
    65 (*** transient ***)
    66 
    66 
    67 lemma transient_type: "transient(A)<=program"
    67 lemma transient_type: "transient(A)<=program"
    79 apply (simp add: transient_def st_set_def, clarify)
    79 apply (simp add: transient_def st_set_def, clarify)
    80 apply (blast intro!: rev_bexI)
    80 apply (blast intro!: rev_bexI)
    81 done
    81 done
    82 
    82 
    83 lemma transientI: 
    83 lemma transientI: 
    84 "[|act \<in> Acts(F); A <= domain(act); act``A <= state-A;  
    84 "[|act \<in> Acts(F); A \<subseteq> domain(act); act``A \<subseteq> state-A;  
    85     F \<in> program; st_set(A)|] ==> F \<in> transient(A)"
    85     F \<in> program; st_set(A)|] ==> F \<in> transient(A)"
    86 by (simp add: transient_def, blast)
    86 by (simp add: transient_def, blast)
    87 
    87 
    88 lemma transientE: 
    88 lemma transientE: 
    89      "[| F \<in> transient(A);  
    89      "[| F \<in> transient(A);  
    90          !!act. [| act \<in> Acts(F);  A <= domain(act); act``A <= state-A|]==>P|]
    90          !!act. [| act \<in> Acts(F);  A \<subseteq> domain(act); act``A \<subseteq> state-A|]==>P|]
    91       ==>P"
    91       ==>P"
    92 by (simp add: transient_def, blast)
    92 by (simp add: transient_def, blast)
    93 
    93 
    94 lemma transient_state: "transient(state) = 0"
    94 lemma transient_state: "transient(state) = 0"
    95 apply (simp add: transient_def)
    95 apply (simp add: transient_def)
   116 
   116 
   117 lemma ensures_type: "A ensures B <=program"
   117 lemma ensures_type: "A ensures B <=program"
   118 by (simp add: ensures_def constrains_def, auto)
   118 by (simp add: ensures_def constrains_def, auto)
   119 
   119 
   120 lemma ensuresI: 
   120 lemma ensuresI: 
   121 "[|F:(A-B) co (A Un B); F \<in> transient(A-B)|]==>F \<in> A ensures B"
   121 "[|F:(A-B) co (A \<union> B); F \<in> transient(A-B)|]==>F \<in> A ensures B"
   122 apply (unfold ensures_def)
   122 apply (unfold ensures_def)
   123 apply (auto simp add: transient_type [THEN subsetD])
   123 apply (auto simp add: transient_type [THEN subsetD])
   124 done
   124 done
   125 
   125 
   126 (* Added by Sidi, from Misra's notes, Progress chapter, exercise 4 *)
   126 (* Added by Sidi, from Misra's notes, Progress chapter, exercise 4 *)
   127 lemma ensuresI2: "[| F \<in> A co A Un B; F \<in> transient(A) |] ==> F \<in> A ensures B"
   127 lemma ensuresI2: "[| F \<in> A co A \<union> B; F \<in> transient(A) |] ==> F \<in> A ensures B"
   128 apply (drule_tac B = "A-B" in constrains_weaken_L)
   128 apply (drule_tac B = "A-B" in constrains_weaken_L)
   129 apply (drule_tac [2] B = "A-B" in transient_strengthen)
   129 apply (drule_tac [2] B = "A-B" in transient_strengthen)
   130 apply (auto simp add: ensures_def transient_type [THEN subsetD])
   130 apply (auto simp add: ensures_def transient_type [THEN subsetD])
   131 done
   131 done
   132 
   132 
   133 lemma ensuresD: "F \<in> A ensures B ==> F:(A-B) co (A Un B) & F \<in> transient (A-B)"
   133 lemma ensuresD: "F \<in> A ensures B ==> F:(A-B) co (A \<union> B) & F \<in> transient (A-B)"
   134 by (unfold ensures_def, auto)
   134 by (unfold ensures_def, auto)
   135 
   135 
   136 lemma ensures_weaken_R: "[|F \<in> A ensures A'; A'<=B' |] ==> F \<in> A ensures B'"
   136 lemma ensures_weaken_R: "[|F \<in> A ensures A'; A'<=B' |] ==> F \<in> A ensures B'"
   137 apply (unfold ensures_def)
   137 apply (unfold ensures_def)
   138 apply (blast intro: transient_strengthen constrains_weaken)
   138 apply (blast intro: transient_strengthen constrains_weaken)
   139 done
   139 done
   140 
   140 
   141 (*The L-version (precondition strengthening) fails, but we have this*) 
   141 (*The L-version (precondition strengthening) fails, but we have this*) 
   142 lemma stable_ensures_Int: 
   142 lemma stable_ensures_Int: 
   143      "[| F \<in> stable(C);  F \<in> A ensures B |] ==> F:(C Int A) ensures (C Int B)"
   143      "[| F \<in> stable(C);  F \<in> A ensures B |] ==> F:(C \<inter> A) ensures (C \<inter> B)"
   144  
   144  
   145 apply (unfold ensures_def)
   145 apply (unfold ensures_def)
   146 apply (simp (no_asm) add: Int_Un_distrib [symmetric] Diff_Int_distrib [symmetric])
   146 apply (simp (no_asm) add: Int_Un_distrib [symmetric] Diff_Int_distrib [symmetric])
   147 apply (blast intro: transient_strengthen stable_constrains_Int constrains_weaken)
   147 apply (blast intro: transient_strengthen stable_constrains_Int constrains_weaken)
   148 done
   148 done
   149 
   149 
   150 lemma stable_transient_ensures: "[|F \<in> stable(A);  F \<in> transient(C); A<=B Un C|] ==> F \<in> A ensures B"
   150 lemma stable_transient_ensures: "[|F \<in> stable(A);  F \<in> transient(C); A<=B \<union> C|] ==> F \<in> A ensures B"
   151 apply (frule stable_type [THEN subsetD])
   151 apply (frule stable_type [THEN subsetD])
   152 apply (simp add: ensures_def stable_def)
   152 apply (simp add: ensures_def stable_def)
   153 apply (blast intro: transient_strengthen constrains_weaken)
   153 apply (blast intro: transient_strengthen constrains_weaken)
   154 done
   154 done
   155 
   155 
   156 lemma ensures_eq: "(A ensures B) = (A unless B) Int transient (A-B)"
   156 lemma ensures_eq: "(A ensures B) = (A unless B) \<inter> transient (A-B)"
   157 by (auto simp add: ensures_def unless_def)
   157 by (auto simp add: ensures_def unless_def)
   158 
   158 
   159 lemma subset_imp_ensures: "[| F \<in> program; A<=B  |] ==> F \<in> A ensures B"
   159 lemma subset_imp_ensures: "[| F \<in> program; A<=B  |] ==> F \<in> A ensures B"
   160 by (auto simp add: ensures_def constrains_def transient_def st_set_def)
   160 by (auto simp add: ensures_def constrains_def transient_def st_set_def)
   161 
   161 
   162 (*** leadsTo ***)
   162 (*** leadsTo ***)
   163 lemmas leads_left = leads.dom_subset [THEN subsetD, THEN SigmaD1]
   163 lemmas leads_left = leads.dom_subset [THEN subsetD, THEN SigmaD1]
   164 lemmas leads_right = leads.dom_subset [THEN subsetD, THEN SigmaD2]
   164 lemmas leads_right = leads.dom_subset [THEN subsetD, THEN SigmaD2]
   165 
   165 
   166 lemma leadsTo_type: "A leadsTo B <= program"
   166 lemma leadsTo_type: "A leadsTo B \<subseteq> program"
   167 by (unfold leadsTo_def, auto)
   167 by (unfold leadsTo_def, auto)
   168 
   168 
   169 lemma leadsToD2: 
   169 lemma leadsToD2: 
   170 "F \<in> A leadsTo B ==> F \<in> program & st_set(A) & st_set(B)"
   170 "F \<in> A leadsTo B ==> F \<in> program & st_set(A) & st_set(B)"
   171 apply (unfold leadsTo_def st_set_def)
   171 apply (unfold leadsTo_def st_set_def)
   194 apply (unfold transient_def)
   194 apply (unfold transient_def)
   195 apply (blast intro: ensuresI [THEN leadsTo_Basis] constrains_weaken transientI)
   195 apply (blast intro: ensuresI [THEN leadsTo_Basis] constrains_weaken transientI)
   196 done
   196 done
   197 
   197 
   198 (*Useful with cancellation, disjunction*)
   198 (*Useful with cancellation, disjunction*)
   199 lemma leadsTo_Un_duplicate: "F \<in> A leadsTo (A' Un A') ==> F \<in> A leadsTo A'"
   199 lemma leadsTo_Un_duplicate: "F \<in> A leadsTo (A' \<union> A') ==> F \<in> A leadsTo A'"
   200 by simp
   200 by simp
   201 
   201 
   202 lemma leadsTo_Un_duplicate2:
   202 lemma leadsTo_Un_duplicate2:
   203      "F \<in> A leadsTo (A' Un C Un C) ==> F \<in> A leadsTo (A' Un C)"
   203      "F \<in> A leadsTo (A' \<union> C \<union> C) ==> F \<in> A leadsTo (A' \<union> C)"
   204 by (simp add: Un_ac)
   204 by (simp add: Un_ac)
   205 
   205 
   206 (*The Union introduction rule as we should have liked to state it*)
   206 (*The Union introduction rule as we should have liked to state it*)
   207 lemma leadsTo_Union: 
   207 lemma leadsTo_Union: 
   208     "[|!!A. A \<in> S ==> F \<in> A leadsTo B; F \<in> program; st_set(B)|]
   208     "[|!!A. A \<in> S ==> F \<in> A leadsTo B; F \<in> program; st_set(B)|]
   209      ==> F \<in> Union(S) leadsTo B"
   209      ==> F \<in> \<Union>(S) leadsTo B"
   210 apply (unfold leadsTo_def st_set_def)
   210 apply (unfold leadsTo_def st_set_def)
   211 apply (blast intro: leads.Union dest: leads_left)
   211 apply (blast intro: leads.Union dest: leads_left)
   212 done
   212 done
   213 
   213 
   214 lemma leadsTo_Union_Int: 
   214 lemma leadsTo_Union_Int: 
   215     "[|!!A. A \<in> S ==>F : (A Int C) leadsTo B; F \<in> program; st_set(B)|]  
   215     "[|!!A. A \<in> S ==>F \<in> (A \<inter> C) leadsTo B; F \<in> program; st_set(B)|]  
   216      ==> F : (Union(S)Int C)leadsTo B"
   216      ==> F \<in> (\<Union>(S)Int C)leadsTo B"
   217 apply (unfold leadsTo_def st_set_def)
   217 apply (unfold leadsTo_def st_set_def)
   218 apply (simp only: Int_Union_Union)
   218 apply (simp only: Int_Union_Union)
   219 apply (blast dest: leads_left intro: leads.Union)
   219 apply (blast dest: leads_left intro: leads.Union)
   220 done
   220 done
   221 
   221 
   226 apply (blast dest: leads_left intro: leads.Union)
   226 apply (blast dest: leads_left intro: leads.Union)
   227 done
   227 done
   228 
   228 
   229 (* Binary union introduction rule *)
   229 (* Binary union introduction rule *)
   230 lemma leadsTo_Un:
   230 lemma leadsTo_Un:
   231      "[| F \<in> A leadsTo C; F \<in> B leadsTo C |] ==> F \<in> (A Un B) leadsTo C"
   231      "[| F \<in> A leadsTo C; F \<in> B leadsTo C |] ==> F \<in> (A \<union> B) leadsTo C"
   232 apply (subst Un_eq_Union)
   232 apply (subst Un_eq_Union)
   233 apply (blast intro: leadsTo_Union dest: leadsToD2)
   233 apply (blast intro: leadsTo_Union dest: leadsToD2)
   234 done
   234 done
   235 
   235 
   236 lemma single_leadsTo_I:
   236 lemma single_leadsTo_I:
   241 done
   241 done
   242 
   242 
   243 lemma leadsTo_refl: "[| F \<in> program; st_set(A) |] ==> F \<in> A leadsTo A"
   243 lemma leadsTo_refl: "[| F \<in> program; st_set(A) |] ==> F \<in> A leadsTo A"
   244 by (blast intro: subset_imp_leadsTo)
   244 by (blast intro: subset_imp_leadsTo)
   245 
   245 
   246 lemma leadsTo_refl_iff: "F \<in> A leadsTo A <-> F \<in> program & st_set(A)"
   246 lemma leadsTo_refl_iff: "F \<in> A leadsTo A \<longleftrightarrow> F \<in> program & st_set(A)"
   247 by (auto intro: leadsTo_refl dest: leadsToD2)
   247 by (auto intro: leadsTo_refl dest: leadsToD2)
   248 
   248 
   249 lemma empty_leadsTo: "F \<in> 0 leadsTo B <-> (F \<in> program & st_set(B))"
   249 lemma empty_leadsTo: "F \<in> 0 leadsTo B \<longleftrightarrow> (F \<in> program & st_set(B))"
   250 by (auto intro: subset_imp_leadsTo dest: leadsToD2)
   250 by (auto intro: subset_imp_leadsTo dest: leadsToD2)
   251 declare empty_leadsTo [iff]
   251 declare empty_leadsTo [iff]
   252 
   252 
   253 lemma leadsTo_state: "F \<in> A leadsTo state <-> (F \<in> program & st_set(A))"
   253 lemma leadsTo_state: "F \<in> A leadsTo state \<longleftrightarrow> (F \<in> program & st_set(A))"
   254 by (auto intro: subset_imp_leadsTo dest: leadsToD2 st_setD)
   254 by (auto intro: subset_imp_leadsTo dest: leadsToD2 st_setD)
   255 declare leadsTo_state [iff]
   255 declare leadsTo_state [iff]
   256 
   256 
   257 lemma leadsTo_weaken_R: "[| F \<in> A leadsTo A'; A'<=B'; st_set(B') |] ==> F \<in> A leadsTo B'"
   257 lemma leadsTo_weaken_R: "[| F \<in> A leadsTo A'; A'<=B'; st_set(B') |] ==> F \<in> A leadsTo B'"
   258 by (blast dest: leadsToD2 intro: subset_imp_leadsTo leadsTo_Trans)
   258 by (blast dest: leadsToD2 intro: subset_imp_leadsTo leadsTo_Trans)
   273 apply (rule leadsTo_weaken_R)
   273 apply (rule leadsTo_weaken_R)
   274 apply (auto simp add: transient_imp_leadsTo)
   274 apply (auto simp add: transient_imp_leadsTo)
   275 done
   275 done
   276 
   276 
   277 (*Distributes over binary unions*)
   277 (*Distributes over binary unions*)
   278 lemma leadsTo_Un_distrib: "F:(A Un B) leadsTo C  <->  (F \<in> A leadsTo C & F \<in> B leadsTo C)"
   278 lemma leadsTo_Un_distrib: "F:(A \<union> B) leadsTo C  \<longleftrightarrow>  (F \<in> A leadsTo C & F \<in> B leadsTo C)"
   279 by (blast intro: leadsTo_Un leadsTo_weaken_L)
   279 by (blast intro: leadsTo_Un leadsTo_weaken_L)
   280 
   280 
   281 lemma leadsTo_UN_distrib: 
   281 lemma leadsTo_UN_distrib: 
   282 "(F:(\<Union>i \<in> I. A(i)) leadsTo B)<-> ((\<forall>i \<in> I. F \<in> A(i) leadsTo B) & F \<in> program & st_set(B))"
   282 "(F:(\<Union>i \<in> I. A(i)) leadsTo B)\<longleftrightarrow> ((\<forall>i \<in> I. F \<in> A(i) leadsTo B) & F \<in> program & st_set(B))"
   283 apply (blast dest: leadsToD2 intro: leadsTo_UN leadsTo_weaken_L)
   283 apply (blast dest: leadsToD2 intro: leadsTo_UN leadsTo_weaken_L)
   284 done
   284 done
   285 
   285 
   286 lemma leadsTo_Union_distrib: "(F \<in> Union(S) leadsTo B) <->  (\<forall>A \<in> S. F \<in> A leadsTo B) & F \<in> program & st_set(B)"
   286 lemma leadsTo_Union_distrib: "(F \<in> \<Union>(S) leadsTo B) \<longleftrightarrow>  (\<forall>A \<in> S. F \<in> A leadsTo B) & F \<in> program & st_set(B)"
   287 by (blast dest: leadsToD2 intro: leadsTo_Union leadsTo_weaken_L)
   287 by (blast dest: leadsToD2 intro: leadsTo_Union leadsTo_weaken_L)
   288 
   288 
   289 text{*Set difference: maybe combine with @{text leadsTo_weaken_L}??*}
   289 text{*Set difference: maybe combine with @{text leadsTo_weaken_L}??*}
   290 lemma leadsTo_Diff:
   290 lemma leadsTo_Diff:
   291      "[| F: (A-B) leadsTo C; F \<in> B leadsTo C; st_set(C) |]
   291      "[| F: (A-B) leadsTo C; F \<in> B leadsTo C; st_set(C) |]
   298 apply (rule leadsTo_Union)
   298 apply (rule leadsTo_Union)
   299 apply (auto intro: leadsTo_weaken_R dest: leadsToD2) 
   299 apply (auto intro: leadsTo_weaken_R dest: leadsToD2) 
   300 done
   300 done
   301 
   301 
   302 (*Binary union version*)
   302 (*Binary union version*)
   303 lemma leadsTo_Un_Un: "[| F \<in> A leadsTo A'; F \<in> B leadsTo B' |] ==> F \<in> (A Un B) leadsTo (A' Un B')"
   303 lemma leadsTo_Un_Un: "[| F \<in> A leadsTo A'; F \<in> B leadsTo B' |] ==> F \<in> (A \<union> B) leadsTo (A' \<union> B')"
   304 apply (subgoal_tac "st_set (A) & st_set (A') & st_set (B) & st_set (B') ")
   304 apply (subgoal_tac "st_set (A) & st_set (A') & st_set (B) & st_set (B') ")
   305 prefer 2 apply (blast dest: leadsToD2)
   305 prefer 2 apply (blast dest: leadsToD2)
   306 apply (blast intro: leadsTo_Un leadsTo_weaken_R)
   306 apply (blast intro: leadsTo_Un leadsTo_weaken_R)
   307 done
   307 done
   308 
   308 
   309 (** The cancellation law **)
   309 (** The cancellation law **)
   310 lemma leadsTo_cancel2: "[|F \<in> A leadsTo (A' Un B); F \<in> B leadsTo B'|] ==> F \<in> A leadsTo (A' Un B')"
   310 lemma leadsTo_cancel2: "[|F \<in> A leadsTo (A' \<union> B); F \<in> B leadsTo B'|] ==> F \<in> A leadsTo (A' \<union> B')"
   311 apply (subgoal_tac "st_set (A) & st_set (A') & st_set (B) & st_set (B') &F \<in> program")
   311 apply (subgoal_tac "st_set (A) & st_set (A') & st_set (B) & st_set (B') &F \<in> program")
   312 prefer 2 apply (blast dest: leadsToD2)
   312 prefer 2 apply (blast dest: leadsToD2)
   313 apply (blast intro: leadsTo_Trans leadsTo_Un_Un leadsTo_refl)
   313 apply (blast intro: leadsTo_Trans leadsTo_Un_Un leadsTo_refl)
   314 done
   314 done
   315 
   315 
   316 lemma leadsTo_cancel_Diff2: "[|F \<in> A leadsTo (A' Un B); F \<in> (B-A') leadsTo B'|]==> F \<in> A leadsTo (A' Un B')"
   316 lemma leadsTo_cancel_Diff2: "[|F \<in> A leadsTo (A' \<union> B); F \<in> (B-A') leadsTo B'|]==> F \<in> A leadsTo (A' \<union> B')"
   317 apply (rule leadsTo_cancel2)
   317 apply (rule leadsTo_cancel2)
   318 prefer 2 apply assumption
   318 prefer 2 apply assumption
   319 apply (blast dest: leadsToD2 intro: leadsTo_weaken_R)
   319 apply (blast dest: leadsToD2 intro: leadsTo_weaken_R)
   320 done
   320 done
   321 
   321 
   322 
   322 
   323 lemma leadsTo_cancel1: "[| F \<in> A leadsTo (B Un A'); F \<in> B leadsTo B' |] ==> F \<in> A leadsTo (B' Un A')"
   323 lemma leadsTo_cancel1: "[| F \<in> A leadsTo (B \<union> A'); F \<in> B leadsTo B' |] ==> F \<in> A leadsTo (B' \<union> A')"
   324 apply (simp add: Un_commute)
   324 apply (simp add: Un_commute)
   325 apply (blast intro!: leadsTo_cancel2)
   325 apply (blast intro!: leadsTo_cancel2)
   326 done
   326 done
   327 
   327 
   328 lemma leadsTo_cancel_Diff1:
   328 lemma leadsTo_cancel_Diff1:
   329      "[|F \<in> A leadsTo (B Un A'); F: (B-A') leadsTo B'|]==> F \<in> A leadsTo (B' Un A')"
   329      "[|F \<in> A leadsTo (B \<union> A'); F: (B-A') leadsTo B'|]==> F \<in> A leadsTo (B' \<union> A')"
   330 apply (rule leadsTo_cancel1)
   330 apply (rule leadsTo_cancel1)
   331 prefer 2 apply assumption
   331 prefer 2 apply assumption
   332 apply (blast intro: leadsTo_weaken_R dest: leadsToD2)
   332 apply (blast intro: leadsTo_weaken_R dest: leadsToD2)
   333 done
   333 done
   334 
   334 
   337   assumes major: "F \<in> za leadsTo zb"
   337   assumes major: "F \<in> za leadsTo zb"
   338       and basis: "!!A B. [|F \<in> A ensures B; st_set(A); st_set(B)|] ==> P(A,B)"
   338       and basis: "!!A B. [|F \<in> A ensures B; st_set(A); st_set(B)|] ==> P(A,B)"
   339       and trans: "!!A B C. [| F \<in> A leadsTo B; P(A, B);  
   339       and trans: "!!A B C. [| F \<in> A leadsTo B; P(A, B);  
   340                               F \<in> B leadsTo C; P(B, C) |] ==> P(A,C)"
   340                               F \<in> B leadsTo C; P(B, C) |] ==> P(A,C)"
   341       and union: "!!B S. [| \<forall>A \<in> S. F \<in> A leadsTo B; \<forall>A \<in> S. P(A,B); 
   341       and union: "!!B S. [| \<forall>A \<in> S. F \<in> A leadsTo B; \<forall>A \<in> S. P(A,B); 
   342                            st_set(B); \<forall>A \<in> S. st_set(A)|] ==> P(Union(S), B)"
   342                            st_set(B); \<forall>A \<in> S. st_set(A)|] ==> P(\<Union>(S), B)"
   343   shows "P(za, zb)"
   343   shows "P(za, zb)"
   344 apply (cut_tac major)
   344 apply (cut_tac major)
   345 apply (unfold leadsTo_def, clarify) 
   345 apply (unfold leadsTo_def, clarify) 
   346 apply (erule leads.induct) 
   346 apply (erule leads.induct) 
   347   apply (blast intro: basis [unfolded st_set_def])
   347   apply (blast intro: basis [unfolded st_set_def])
   352 
   352 
   353 (* Added by Sidi, an induction rule without ensures *)
   353 (* Added by Sidi, an induction rule without ensures *)
   354 lemma leadsTo_induct2:
   354 lemma leadsTo_induct2:
   355   assumes major: "F \<in> za leadsTo zb"
   355   assumes major: "F \<in> za leadsTo zb"
   356       and basis1: "!!A B. [| A<=B; st_set(B) |] ==> P(A, B)"
   356       and basis1: "!!A B. [| A<=B; st_set(B) |] ==> P(A, B)"
   357       and basis2: "!!A B. [| F \<in> A co A Un B; F \<in> transient(A); st_set(B) |] 
   357       and basis2: "!!A B. [| F \<in> A co A \<union> B; F \<in> transient(A); st_set(B) |] 
   358                           ==> P(A, B)"
   358                           ==> P(A, B)"
   359       and trans: "!!A B C. [| F \<in> A leadsTo B; P(A, B);  
   359       and trans: "!!A B C. [| F \<in> A leadsTo B; P(A, B);  
   360                               F \<in> B leadsTo C; P(B, C) |] ==> P(A,C)"
   360                               F \<in> B leadsTo C; P(B, C) |] ==> P(A,C)"
   361       and union: "!!B S. [| \<forall>A \<in> S. F \<in> A leadsTo B; \<forall>A \<in> S. P(A,B); 
   361       and union: "!!B S. [| \<forall>A \<in> S. F \<in> A leadsTo B; \<forall>A \<in> S. P(A,B); 
   362                            st_set(B); \<forall>A \<in> S. st_set(A)|] ==> P(Union(S), B)"
   362                            st_set(B); \<forall>A \<in> S. st_set(A)|] ==> P(\<Union>(S), B)"
   363   shows "P(za, zb)"
   363   shows "P(za, zb)"
   364 apply (cut_tac major)
   364 apply (cut_tac major)
   365 apply (erule leadsTo_induct)
   365 apply (erule leadsTo_induct)
   366 apply (auto intro: trans union)
   366 apply (auto intro: trans union)
   367 apply (simp add: ensures_def, clarify)
   367 apply (simp add: ensures_def, clarify)
   368 apply (frule constrainsD2)
   368 apply (frule constrainsD2)
   369 apply (drule_tac B' = " (A-B) Un B" in constrains_weaken_R)
   369 apply (drule_tac B' = " (A-B) \<union> B" in constrains_weaken_R)
   370 apply blast
   370 apply blast
   371 apply (frule ensuresI2 [THEN leadsTo_Basis])
   371 apply (frule ensuresI2 [THEN leadsTo_Basis])
   372 apply (drule_tac [4] basis2, simp_all)
   372 apply (drule_tac [4] basis2, simp_all)
   373 apply (frule_tac A1 = A and B = B in Int_lower2 [THEN basis1])
   373 apply (frule_tac A1 = A and B = B in Int_lower2 [THEN basis1])
   374 apply (subgoal_tac "A=Union ({A - B, A Int B}) ")
   374 apply (subgoal_tac "A=\<Union>({A - B, A \<inter> B}) ")
   375 prefer 2 apply blast
   375 prefer 2 apply blast
   376 apply (erule ssubst)
   376 apply (erule ssubst)
   377 apply (rule union)
   377 apply (rule union)
   378 apply (auto intro: subset_imp_leadsTo)
   378 apply (auto intro: subset_imp_leadsTo)
   379 done
   379 done
   383 (*Lemma is the weak version: can't see how to do it in one step*)
   383 (*Lemma is the weak version: can't see how to do it in one step*)
   384 lemma leadsTo_induct_pre_aux: 
   384 lemma leadsTo_induct_pre_aux: 
   385   "[| F \<in> za leadsTo zb;   
   385   "[| F \<in> za leadsTo zb;   
   386       P(zb);  
   386       P(zb);  
   387       !!A B. [| F \<in> A ensures B;  P(B); st_set(A); st_set(B) |] ==> P(A);  
   387       !!A B. [| F \<in> A ensures B;  P(B); st_set(A); st_set(B) |] ==> P(A);  
   388       !!S. [| \<forall>A \<in> S. P(A); \<forall>A \<in> S. st_set(A) |] ==> P(Union(S))  
   388       !!S. [| \<forall>A \<in> S. P(A); \<forall>A \<in> S. st_set(A) |] ==> P(\<Union>(S))  
   389    |] ==> P(za)"
   389    |] ==> P(za)"
   390 txt{*by induction on this formula*}
   390 txt{*by induction on this formula*}
   391 apply (subgoal_tac "P (zb) --> P (za) ")
   391 apply (subgoal_tac "P (zb) \<longrightarrow> P (za) ")
   392 txt{*now solve first subgoal: this formula is sufficient*}
   392 txt{*now solve first subgoal: this formula is sufficient*}
   393 apply (blast intro: leadsTo_refl)
   393 apply (blast intro: leadsTo_refl)
   394 apply (erule leadsTo_induct)
   394 apply (erule leadsTo_induct)
   395 apply (blast+)
   395 apply (blast+)
   396 done
   396 done
   398 
   398 
   399 lemma leadsTo_induct_pre: 
   399 lemma leadsTo_induct_pre: 
   400   "[| F \<in> za leadsTo zb;   
   400   "[| F \<in> za leadsTo zb;   
   401       P(zb);  
   401       P(zb);  
   402       !!A B. [| F \<in> A ensures B;  F \<in> B leadsTo zb;  P(B); st_set(A) |] ==> P(A);  
   402       !!A B. [| F \<in> A ensures B;  F \<in> B leadsTo zb;  P(B); st_set(A) |] ==> P(A);  
   403       !!S. \<forall>A \<in> S. F \<in> A leadsTo zb & P(A) & st_set(A) ==> P(Union(S))  
   403       !!S. \<forall>A \<in> S. F \<in> A leadsTo zb & P(A) & st_set(A) ==> P(\<Union>(S))  
   404    |] ==> P(za)"
   404    |] ==> P(za)"
   405 apply (subgoal_tac " (F \<in> za leadsTo zb) & P (za) ")
   405 apply (subgoal_tac " (F \<in> za leadsTo zb) & P (za) ")
   406 apply (erule conjunct2)
   406 apply (erule conjunct2)
   407 apply (frule leadsToD2) 
   407 apply (frule leadsToD2) 
   408 apply (erule leadsTo_induct_pre_aux)
   408 apply (erule leadsTo_induct_pre_aux)
   424 subsection{*PSP: Progress-Safety-Progress*}
   424 subsection{*PSP: Progress-Safety-Progress*}
   425 
   425 
   426 text{*Special case of PSP: Misra's "stable conjunction"*}
   426 text{*Special case of PSP: Misra's "stable conjunction"*}
   427 
   427 
   428 lemma psp_stable: 
   428 lemma psp_stable: 
   429    "[| F \<in> A leadsTo A'; F \<in> stable(B) |] ==> F:(A Int B) leadsTo (A' Int B)"
   429    "[| F \<in> A leadsTo A'; F \<in> stable(B) |] ==> F:(A \<inter> B) leadsTo (A' \<inter> B)"
   430 apply (unfold stable_def)
   430 apply (unfold stable_def)
   431 apply (frule leadsToD2) 
   431 apply (frule leadsToD2) 
   432 apply (erule leadsTo_induct)
   432 apply (erule leadsTo_induct)
   433 prefer 3 apply (blast intro: leadsTo_Union_Int)
   433 prefer 3 apply (blast intro: leadsTo_Union_Int)
   434 prefer 2 apply (blast intro: leadsTo_Trans)
   434 prefer 2 apply (blast intro: leadsTo_Trans)
   436 apply (simp add: ensures_def Diff_Int_distrib2 [symmetric] Int_Un_distrib2 [symmetric])
   436 apply (simp add: ensures_def Diff_Int_distrib2 [symmetric] Int_Un_distrib2 [symmetric])
   437 apply (auto intro: transient_strengthen constrains_Int)
   437 apply (auto intro: transient_strengthen constrains_Int)
   438 done
   438 done
   439 
   439 
   440 
   440 
   441 lemma psp_stable2: "[|F \<in> A leadsTo A'; F \<in> stable(B) |]==>F: (B Int A) leadsTo (B Int A')"
   441 lemma psp_stable2: "[|F \<in> A leadsTo A'; F \<in> stable(B) |]==>F: (B \<inter> A) leadsTo (B \<inter> A')"
   442 apply (simp (no_asm_simp) add: psp_stable Int_ac)
   442 apply (simp (no_asm_simp) add: psp_stable Int_ac)
   443 done
   443 done
   444 
   444 
   445 lemma psp_ensures: 
   445 lemma psp_ensures: 
   446 "[| F \<in> A ensures A'; F \<in> B co B' |]==> F: (A Int B') ensures ((A' Int B) Un (B' - B))"
   446 "[| F \<in> A ensures A'; F \<in> B co B' |]==> F: (A \<inter> B') ensures ((A' \<inter> B) \<union> (B' - B))"
   447 apply (unfold ensures_def constrains_def st_set_def)
   447 apply (unfold ensures_def constrains_def st_set_def)
   448 (*speeds up the proof*)
   448 (*speeds up the proof*)
   449 apply clarify
   449 apply clarify
   450 apply (blast intro: transient_strengthen)
   450 apply (blast intro: transient_strengthen)
   451 done
   451 done
   452 
   452 
   453 lemma psp: 
   453 lemma psp: 
   454 "[|F \<in> A leadsTo A'; F \<in> B co B'; st_set(B')|]==> F:(A Int B') leadsTo ((A' Int B) Un (B' - B))"
   454 "[|F \<in> A leadsTo A'; F \<in> B co B'; st_set(B')|]==> F:(A \<inter> B') leadsTo ((A' \<inter> B) \<union> (B' - B))"
   455 apply (subgoal_tac "F \<in> program & st_set (A) & st_set (A') & st_set (B) ")
   455 apply (subgoal_tac "F \<in> program & st_set (A) & st_set (A') & st_set (B) ")
   456 prefer 2 apply (blast dest!: constrainsD2 leadsToD2)
   456 prefer 2 apply (blast dest!: constrainsD2 leadsToD2)
   457 apply (erule leadsTo_induct)
   457 apply (erule leadsTo_induct)
   458 prefer 3 apply (blast intro: leadsTo_Union_Int)
   458 prefer 3 apply (blast intro: leadsTo_Union_Int)
   459  txt{*Basis case*}
   459  txt{*Basis case*}
   465 apply (blast intro: leadsTo_weaken_L dest: constrains_imp_subset)
   465 apply (blast intro: leadsTo_weaken_L dest: constrains_imp_subset)
   466 done
   466 done
   467 
   467 
   468 
   468 
   469 lemma psp2: "[| F \<in> A leadsTo A'; F \<in> B co B'; st_set(B') |]  
   469 lemma psp2: "[| F \<in> A leadsTo A'; F \<in> B co B'; st_set(B') |]  
   470     ==> F \<in> (B' Int A) leadsTo ((B Int A') Un (B' - B))"
   470     ==> F \<in> (B' \<inter> A) leadsTo ((B \<inter> A') \<union> (B' - B))"
   471 by (simp (no_asm_simp) add: psp Int_ac)
   471 by (simp (no_asm_simp) add: psp Int_ac)
   472 
   472 
   473 lemma psp_unless: 
   473 lemma psp_unless: 
   474    "[| F \<in> A leadsTo A';  F \<in> B unless B'; st_set(B); st_set(B') |]  
   474    "[| F \<in> A leadsTo A';  F \<in> B unless B'; st_set(B); st_set(B') |]  
   475     ==> F \<in> (A Int B) leadsTo ((A' Int B) Un B')"
   475     ==> F \<in> (A \<inter> B) leadsTo ((A' \<inter> B) \<union> B')"
   476 apply (unfold unless_def)
   476 apply (unfold unless_def)
   477 apply (subgoal_tac "st_set (A) &st_set (A') ")
   477 apply (subgoal_tac "st_set (A) &st_set (A') ")
   478 prefer 2 apply (blast dest: leadsToD2)
   478 prefer 2 apply (blast dest: leadsToD2)
   479 apply (drule psp, assumption, blast)
   479 apply (drule psp, assumption, blast)
   480 apply (blast intro: leadsTo_weaken)
   480 apply (blast intro: leadsTo_weaken)
   486 (** The most general rule \<in> r is any wf relation; f is any variant function **)
   486 (** The most general rule \<in> r is any wf relation; f is any variant function **)
   487 lemma leadsTo_wf_induct_aux: "[| wf(r);  
   487 lemma leadsTo_wf_induct_aux: "[| wf(r);  
   488          m \<in> I;  
   488          m \<in> I;  
   489          field(r)<=I;  
   489          field(r)<=I;  
   490          F \<in> program; st_set(B); 
   490          F \<in> program; st_set(B); 
   491          \<forall>m \<in> I. F \<in> (A Int f-``{m}) leadsTo                      
   491          \<forall>m \<in> I. F \<in> (A \<inter> f-``{m}) leadsTo                      
   492                     ((A Int f-``(converse(r)``{m})) Un B) |]  
   492                     ((A \<inter> f-``(converse(r)``{m})) \<union> B) |]  
   493       ==> F \<in> (A Int f-``{m}) leadsTo B"
   493       ==> F \<in> (A \<inter> f-``{m}) leadsTo B"
   494 apply (erule_tac a = m in wf_induct2, simp_all)
   494 apply (erule_tac a = m in wf_induct2, simp_all)
   495 apply (subgoal_tac "F \<in> (A Int (f-`` (converse (r) ``{x}))) leadsTo B")
   495 apply (subgoal_tac "F \<in> (A \<inter> (f-`` (converse (r) ``{x}))) leadsTo B")
   496  apply (blast intro: leadsTo_cancel1 leadsTo_Un_duplicate)
   496  apply (blast intro: leadsTo_cancel1 leadsTo_Un_duplicate)
   497 apply (subst vimage_eq_UN)
   497 apply (subst vimage_eq_UN)
   498 apply (simp del: UN_simps add: Int_UN_distrib)
   498 apply (simp del: UN_simps add: Int_UN_distrib)
   499 apply (auto intro: leadsTo_UN simp del: UN_simps simp add: Int_UN_distrib)
   499 apply (auto intro: leadsTo_UN simp del: UN_simps simp add: Int_UN_distrib)
   500 done
   500 done
   502 (** Meta or object quantifier ? **)
   502 (** Meta or object quantifier ? **)
   503 lemma leadsTo_wf_induct: "[| wf(r);  
   503 lemma leadsTo_wf_induct: "[| wf(r);  
   504          field(r)<=I;  
   504          field(r)<=I;  
   505          A<=f-``I;  
   505          A<=f-``I;  
   506          F \<in> program; st_set(A); st_set(B);  
   506          F \<in> program; st_set(A); st_set(B);  
   507          \<forall>m \<in> I. F \<in> (A Int f-``{m}) leadsTo                      
   507          \<forall>m \<in> I. F \<in> (A \<inter> f-``{m}) leadsTo                      
   508                     ((A Int f-``(converse(r)``{m})) Un B) |]  
   508                     ((A \<inter> f-``(converse(r)``{m})) \<union> B) |]  
   509       ==> F \<in> A leadsTo B"
   509       ==> F \<in> A leadsTo B"
   510 apply (rule_tac b = A in subst)
   510 apply (rule_tac b = A in subst)
   511  defer 1
   511  defer 1
   512  apply (rule_tac I = I in leadsTo_UN)
   512  apply (rule_tac I = I in leadsTo_UN)
   513  apply (erule_tac I = I in leadsTo_wf_induct_aux, assumption+, best) 
   513  apply (erule_tac I = I in leadsTo_wf_induct_aux, assumption+, best) 
   533 prefer 2 apply blast
   533 prefer 2 apply blast
   534 apply (simp add: lt_Ord lt_Ord2 Ord_mem_iff_lt)
   534 apply (simp add: lt_Ord lt_Ord2 Ord_mem_iff_lt)
   535 apply (blast intro: lt_trans)
   535 apply (blast intro: lt_trans)
   536 done
   536 done
   537 
   537 
   538 (*Alternative proof is via the lemma F \<in> (A Int f-`(lessThan m)) leadsTo B*)
   538 (*Alternative proof is via the lemma F \<in> (A \<inter> f-`(lessThan m)) leadsTo B*)
   539 lemma lessThan_induct: 
   539 lemma lessThan_induct: 
   540  "[| A<=f-``nat;  
   540  "[| A<=f-``nat;  
   541      F \<in> program; st_set(A); st_set(B);  
   541      F \<in> program; st_set(A); st_set(B);  
   542      \<forall>m \<in> nat. F:(A Int f-``{m}) leadsTo ((A Int f -`` m) Un B) |]  
   542      \<forall>m \<in> nat. F:(A \<inter> f-``{m}) leadsTo ((A \<inter> f -`` m) \<union> B) |]  
   543       ==> F \<in> A leadsTo B"
   543       ==> F \<in> A leadsTo B"
   544 apply (rule_tac A1 = nat and f1 = "%x. x" in wf_measure [THEN leadsTo_wf_induct]) 
   544 apply (rule_tac A1 = nat and f1 = "%x. x" in wf_measure [THEN leadsTo_wf_induct]) 
   545 apply (simp_all add: nat_measure_field)
   545 apply (simp_all add: nat_measure_field)
   546 apply (simp add: ltI Image_inverse_lessThan vimage_def [symmetric])
   546 apply (simp add: ltI Image_inverse_lessThan vimage_def [symmetric])
   547 done
   547 done
   557 apply (unfold st_set_def)
   557 apply (unfold st_set_def)
   558 apply (rule wlt_type)
   558 apply (rule wlt_type)
   559 done
   559 done
   560 declare wlt_st_set [iff]
   560 declare wlt_st_set [iff]
   561 
   561 
   562 lemma wlt_leadsTo_iff: "F \<in> wlt(F, B) leadsTo B <-> (F \<in> program & st_set(B))"
   562 lemma wlt_leadsTo_iff: "F \<in> wlt(F, B) leadsTo B \<longleftrightarrow> (F \<in> program & st_set(B))"
   563 apply (unfold wlt_def)
   563 apply (unfold wlt_def)
   564 apply (blast dest: leadsToD2 intro!: leadsTo_Union)
   564 apply (blast dest: leadsToD2 intro!: leadsTo_Union)
   565 done
   565 done
   566 
   566 
   567 (* [| F \<in> program;  st_set(B) |] ==> F \<in> wlt(F, B) leadsTo B  *)
   567 (* [| F \<in> program;  st_set(B) |] ==> F \<in> wlt(F, B) leadsTo B  *)
   568 lemmas wlt_leadsTo = conjI [THEN wlt_leadsTo_iff [THEN iffD2]]
   568 lemmas wlt_leadsTo = conjI [THEN wlt_leadsTo_iff [THEN iffD2]]
   569 
   569 
   570 lemma leadsTo_subset: "F \<in> A leadsTo B ==> A <= wlt(F, B)"
   570 lemma leadsTo_subset: "F \<in> A leadsTo B ==> A \<subseteq> wlt(F, B)"
   571 apply (unfold wlt_def)
   571 apply (unfold wlt_def)
   572 apply (frule leadsToD2)
   572 apply (frule leadsToD2)
   573 apply (auto simp add: st_set_def)
   573 apply (auto simp add: st_set_def)
   574 done
   574 done
   575 
   575 
   576 (*Misra's property W2*)
   576 (*Misra's property W2*)
   577 lemma leadsTo_eq_subset_wlt: "F \<in> A leadsTo B <-> (A <= wlt(F,B) & F \<in> program & st_set(B))"
   577 lemma leadsTo_eq_subset_wlt: "F \<in> A leadsTo B \<longleftrightarrow> (A \<subseteq> wlt(F,B) & F \<in> program & st_set(B))"
   578 apply auto
   578 apply auto
   579 apply (blast dest: leadsToD2 leadsTo_subset intro: leadsTo_weaken_L wlt_leadsTo)+
   579 apply (blast dest: leadsToD2 leadsTo_subset intro: leadsTo_weaken_L wlt_leadsTo)+
   580 done
   580 done
   581 
   581 
   582 (*Misra's property W4*)
   582 (*Misra's property W4*)
   583 lemma wlt_increasing: "[| F \<in> program; st_set(B) |] ==> B <= wlt(F,B)"
   583 lemma wlt_increasing: "[| F \<in> program; st_set(B) |] ==> B \<subseteq> wlt(F,B)"
   584 apply (rule leadsTo_subset)
   584 apply (rule leadsTo_subset)
   585 apply (simp (no_asm_simp) add: leadsTo_eq_subset_wlt [THEN iff_sym] subset_imp_leadsTo)
   585 apply (simp (no_asm_simp) add: leadsTo_eq_subset_wlt [THEN iff_sym] subset_imp_leadsTo)
   586 done
   586 done
   587 
   587 
   588 (*Used in the Trans case below*)
   588 (*Used in the Trans case below*)
   589 lemma leadsTo_123_aux: 
   589 lemma leadsTo_123_aux: 
   590    "[| B <= A2;  
   590    "[| B \<subseteq> A2;  
   591        F \<in> (A1 - B) co (A1 Un B);  
   591        F \<in> (A1 - B) co (A1 \<union> B);  
   592        F \<in> (A2 - C) co (A2 Un C) |]  
   592        F \<in> (A2 - C) co (A2 \<union> C) |]  
   593     ==> F \<in> (A1 Un A2 - C) co (A1 Un A2 Un C)"
   593     ==> F \<in> (A1 \<union> A2 - C) co (A1 \<union> A2 \<union> C)"
   594 apply (unfold constrains_def st_set_def, blast)
   594 apply (unfold constrains_def st_set_def, blast)
   595 done
   595 done
   596 
   596 
   597 (*Lemma (1,2,3) of Misra's draft book, Chapter 4, "Progress"*)
   597 (*Lemma (1,2,3) of Misra's draft book, Chapter 4, "Progress"*)
   598 (* slightly different from the HOL one \<in> B here is bounded *)
   598 (* slightly different from the HOL one \<in> B here is bounded *)
   599 lemma leadsTo_123: "F \<in> A leadsTo A'  
   599 lemma leadsTo_123: "F \<in> A leadsTo A'  
   600       ==> \<exists>B \<in> Pow(state). A<=B & F \<in> B leadsTo A' & F \<in> (B-A') co (B Un A')"
   600       ==> \<exists>B \<in> Pow(state). A<=B & F \<in> B leadsTo A' & F \<in> (B-A') co (B \<union> A')"
   601 apply (frule leadsToD2)
   601 apply (frule leadsToD2)
   602 apply (erule leadsTo_induct)
   602 apply (erule leadsTo_induct)
   603   txt{*Basis*}
   603   txt{*Basis*}
   604   apply (blast dest: ensuresD constrainsD2 st_setD)
   604   apply (blast dest: ensuresD constrainsD2 st_setD)
   605  txt{*Trans*}
   605  txt{*Trans*}
   606  apply clarify
   606  apply clarify
   607  apply (rule_tac x = "Ba Un Bb" in bexI)
   607  apply (rule_tac x = "Ba \<union> Bb" in bexI)
   608  apply (blast intro: leadsTo_123_aux leadsTo_Un_Un leadsTo_cancel1 leadsTo_Un_duplicate, blast)
   608  apply (blast intro: leadsTo_123_aux leadsTo_Un_Un leadsTo_cancel1 leadsTo_Un_duplicate, blast)
   609 txt{*Union*}
   609 txt{*Union*}
   610 apply (clarify dest!: ball_conj_distrib [THEN iffD1])
   610 apply (clarify dest!: ball_conj_distrib [THEN iffD1])
   611 apply (subgoal_tac "\<exists>y. y \<in> Pi (S, %A. {Ba \<in> Pow (state) . A<=Ba & F \<in> Ba leadsTo B & F \<in> Ba - B co Ba Un B}) ")
   611 apply (subgoal_tac "\<exists>y. y \<in> Pi (S, %A. {Ba \<in> Pow (state) . A<=Ba & F \<in> Ba leadsTo B & F \<in> Ba - B co Ba \<union> B}) ")
   612 defer 1
   612 defer 1
   613 apply (rule AC_ball_Pi, safe)
   613 apply (rule AC_ball_Pi, safe)
   614 apply (rotate_tac 1)
   614 apply (rotate_tac 1)
   615 apply (drule_tac x = x in bspec, blast, blast) 
   615 apply (drule_tac x = x in bspec, blast, blast) 
   616 apply (rule_tac x = "\<Union>A \<in> S. y`A" in bexI, safe)
   616 apply (rule_tac x = "\<Union>A \<in> S. y`A" in bexI, safe)
   631 done
   631 done
   632 
   632 
   633 
   633 
   634 subsection{*Completion: Binary and General Finite versions*}
   634 subsection{*Completion: Binary and General Finite versions*}
   635 
   635 
   636 lemma completion_aux: "[| W = wlt(F, (B' Un C));      
   636 lemma completion_aux: "[| W = wlt(F, (B' \<union> C));      
   637        F \<in> A leadsTo (A' Un C);  F \<in> A' co (A' Un C);    
   637        F \<in> A leadsTo (A' \<union> C);  F \<in> A' co (A' \<union> C);    
   638        F \<in> B leadsTo (B' Un C);  F \<in> B' co (B' Un C) |]  
   638        F \<in> B leadsTo (B' \<union> C);  F \<in> B' co (B' \<union> C) |]  
   639     ==> F \<in> (A Int B) leadsTo ((A' Int B') Un C)"
   639     ==> F \<in> (A \<inter> B) leadsTo ((A' \<inter> B') \<union> C)"
   640 apply (subgoal_tac "st_set (C) &st_set (W) &st_set (W-C) &st_set (A') &st_set (A) & st_set (B) & st_set (B') & F \<in> program")
   640 apply (subgoal_tac "st_set (C) &st_set (W) &st_set (W-C) &st_set (A') &st_set (A) & st_set (B) & st_set (B') & F \<in> program")
   641  prefer 2 
   641  prefer 2 
   642  apply simp 
   642  apply simp 
   643  apply (blast dest!: leadsToD2)
   643  apply (blast dest!: leadsToD2)
   644 apply (subgoal_tac "F \<in> (W-C) co (W Un B' Un C) ")
   644 apply (subgoal_tac "F \<in> (W-C) co (W \<union> B' \<union> C) ")
   645  prefer 2
   645  prefer 2
   646  apply (blast intro!: constrains_weaken [OF constrains_Un [OF _ wlt_constrains_wlt]])
   646  apply (blast intro!: constrains_weaken [OF constrains_Un [OF _ wlt_constrains_wlt]])
   647 apply (subgoal_tac "F \<in> (W-C) co W")
   647 apply (subgoal_tac "F \<in> (W-C) co W")
   648  prefer 2
   648  prefer 2
   649  apply (simp add: wlt_increasing [THEN subset_Un_iff2 [THEN iffD1]] Un_assoc)
   649  apply (simp add: wlt_increasing [THEN subset_Un_iff2 [THEN iffD1]] Un_assoc)
   650 apply (subgoal_tac "F \<in> (A Int W - C) leadsTo (A' Int W Un C) ")
   650 apply (subgoal_tac "F \<in> (A \<inter> W - C) leadsTo (A' \<inter> W \<union> C) ")
   651  prefer 2 apply (blast intro: wlt_leadsTo psp [THEN leadsTo_weaken])
   651  prefer 2 apply (blast intro: wlt_leadsTo psp [THEN leadsTo_weaken])
   652 (** step 13 **)
   652 (** step 13 **)
   653 apply (subgoal_tac "F \<in> (A' Int W Un C) leadsTo (A' Int B' Un C) ")
   653 apply (subgoal_tac "F \<in> (A' \<inter> W \<union> C) leadsTo (A' \<inter> B' \<union> C) ")
   654 apply (drule leadsTo_Diff)
   654 apply (drule leadsTo_Diff)
   655 apply (blast intro: subset_imp_leadsTo dest: leadsToD2 constrainsD2)
   655 apply (blast intro: subset_imp_leadsTo dest: leadsToD2 constrainsD2)
   656 apply (force simp add: st_set_def)
   656 apply (force simp add: st_set_def)
   657 apply (subgoal_tac "A Int B <= A Int W")
   657 apply (subgoal_tac "A \<inter> B \<subseteq> A \<inter> W")
   658 prefer 2 apply (blast dest!: leadsTo_subset intro!: subset_refl [THEN Int_mono])
   658 prefer 2 apply (blast dest!: leadsTo_subset intro!: subset_refl [THEN Int_mono])
   659 apply (blast intro: leadsTo_Trans subset_imp_leadsTo)
   659 apply (blast intro: leadsTo_Trans subset_imp_leadsTo)
   660 txt{*last subgoal*}
   660 txt{*last subgoal*}
   661 apply (rule_tac leadsTo_Un_duplicate2)
   661 apply (rule_tac leadsTo_Un_duplicate2)
   662 apply (rule_tac leadsTo_Un_Un)
   662 apply (rule_tac leadsTo_Un_Un)
   663  prefer 2 apply (blast intro: leadsTo_refl)
   663  prefer 2 apply (blast intro: leadsTo_refl)
   664 apply (rule_tac A'1 = "B' Un C" in wlt_leadsTo[THEN psp2, THEN leadsTo_weaken])
   664 apply (rule_tac A'1 = "B' \<union> C" in wlt_leadsTo[THEN psp2, THEN leadsTo_weaken])
   665 apply blast+
   665 apply blast+
   666 done
   666 done
   667 
   667 
   668 lemmas completion = refl [THEN completion_aux]
   668 lemmas completion = refl [THEN completion_aux]
   669 
   669 
   670 lemma finite_completion_aux:
   670 lemma finite_completion_aux:
   671      "[| I \<in> Fin(X); F \<in> program; st_set(C) |] ==>  
   671      "[| I \<in> Fin(X); F \<in> program; st_set(C) |] ==>  
   672        (\<forall>i \<in> I. F \<in> (A(i)) leadsTo (A'(i) Un C)) -->   
   672        (\<forall>i \<in> I. F \<in> (A(i)) leadsTo (A'(i) \<union> C)) \<longrightarrow>   
   673                      (\<forall>i \<in> I. F \<in> (A'(i)) co (A'(i) Un C)) -->  
   673                      (\<forall>i \<in> I. F \<in> (A'(i)) co (A'(i) \<union> C)) \<longrightarrow>  
   674                    F \<in> (\<Inter>i \<in> I. A(i)) leadsTo ((\<Inter>i \<in> I. A'(i)) Un C)"
   674                    F \<in> (\<Inter>i \<in> I. A(i)) leadsTo ((\<Inter>i \<in> I. A'(i)) \<union> C)"
   675 apply (erule Fin_induct)
   675 apply (erule Fin_induct)
   676 apply (auto simp add: Inter_0)
   676 apply (auto simp add: Inter_0)
   677 apply (rule completion)
   677 apply (rule completion)
   678 apply (auto simp del: INT_simps simp add: INT_extend_simps)
   678 apply (auto simp del: INT_simps simp add: INT_extend_simps)
   679 apply (blast intro: constrains_INT)
   679 apply (blast intro: constrains_INT)
   680 done
   680 done
   681 
   681 
   682 lemma finite_completion: 
   682 lemma finite_completion: 
   683      "[| I \<in> Fin(X);   
   683      "[| I \<in> Fin(X);   
   684          !!i. i \<in> I ==> F \<in> A(i) leadsTo (A'(i) Un C);  
   684          !!i. i \<in> I ==> F \<in> A(i) leadsTo (A'(i) \<union> C);  
   685          !!i. i \<in> I ==> F \<in> A'(i) co (A'(i) Un C); F \<in> program; st_set(C)|]    
   685          !!i. i \<in> I ==> F \<in> A'(i) co (A'(i) \<union> C); F \<in> program; st_set(C)|]    
   686       ==> F \<in> (\<Inter>i \<in> I. A(i)) leadsTo ((\<Inter>i \<in> I. A'(i)) Un C)"
   686       ==> F \<in> (\<Inter>i \<in> I. A(i)) leadsTo ((\<Inter>i \<in> I. A'(i)) \<union> C)"
   687 by (blast intro: finite_completion_aux [THEN mp, THEN mp])
   687 by (blast intro: finite_completion_aux [THEN mp, THEN mp])
   688 
   688 
   689 lemma stable_completion: 
   689 lemma stable_completion: 
   690      "[| F \<in> A leadsTo A';  F \<in> stable(A');    
   690      "[| F \<in> A leadsTo A';  F \<in> stable(A');    
   691          F \<in> B leadsTo B';  F \<in> stable(B') |]  
   691          F \<in> B leadsTo B';  F \<in> stable(B') |]  
   692     ==> F \<in> (A Int B) leadsTo (A' Int B')"
   692     ==> F \<in> (A \<inter> B) leadsTo (A' \<inter> B')"
   693 apply (unfold stable_def)
   693 apply (unfold stable_def)
   694 apply (rule_tac C1 = 0 in completion [THEN leadsTo_weaken_R], simp+)
   694 apply (rule_tac C1 = 0 in completion [THEN leadsTo_weaken_R], simp+)
   695 apply (blast dest: leadsToD2)
   695 apply (blast dest: leadsToD2)
   696 done
   696 done
   697 
   697