src/HOL/UNITY/Transformers.thy
changeset 63146 f1ecba0272f9
parent 62343 24106dc44def
child 67443 3abf6a722518
equal deleted inserted replaced
63145:703edebd1d92 63146:f1ecba0272f9
    11     David Meier,
    11     David Meier,
    12     Progress Properties in Program Refinement and Parallel Composition
    12     Progress Properties in Program Refinement and Parallel Composition
    13     Swiss Federal Institute of Technology Zurich (1997)
    13     Swiss Federal Institute of Technology Zurich (1997)
    14 *)
    14 *)
    15 
    15 
    16 section{*Predicate Transformers*}
    16 section\<open>Predicate Transformers\<close>
    17 
    17 
    18 theory Transformers imports Comp begin
    18 theory Transformers imports Comp begin
    19 
    19 
    20 subsection{*Defining the Predicate Transformers @{term wp},
    20 subsection\<open>Defining the Predicate Transformers @{term wp},
    21    @{term awp} and  @{term wens}*}
    21    @{term awp} and  @{term wens}\<close>
    22 
    22 
    23 definition wp :: "[('a*'a) set, 'a set] => 'a set" where  
    23 definition wp :: "[('a*'a) set, 'a set] => 'a set" where  
    24     --{*Dijkstra's weakest-precondition operator (for an individual command)*}
    24     \<comment>\<open>Dijkstra's weakest-precondition operator (for an individual command)\<close>
    25     "wp act B == - (act^-1 `` (-B))"
    25     "wp act B == - (act^-1 `` (-B))"
    26 
    26 
    27 definition awp :: "['a program, 'a set] => 'a set" where
    27 definition awp :: "['a program, 'a set] => 'a set" where
    28     --{*Dijkstra's weakest-precondition operator (for a program)*}
    28     \<comment>\<open>Dijkstra's weakest-precondition operator (for a program)\<close>
    29     "awp F B == (\<Inter>act \<in> Acts F. wp act B)"
    29     "awp F B == (\<Inter>act \<in> Acts F. wp act B)"
    30 
    30 
    31 definition wens :: "['a program, ('a*'a) set, 'a set] => 'a set" where
    31 definition wens :: "['a program, ('a*'a) set, 'a set] => 'a set" where
    32     --{*The weakest-ensures transformer*}
    32     \<comment>\<open>The weakest-ensures transformer\<close>
    33     "wens F act B == gfp(\<lambda>X. (wp act B \<inter> awp F (B \<union> X)) \<union> B)"
    33     "wens F act B == gfp(\<lambda>X. (wp act B \<inter> awp F (B \<union> X)) \<union> B)"
    34 
    34 
    35 text{*The fundamental theorem for wp*}
    35 text\<open>The fundamental theorem for wp\<close>
    36 theorem wp_iff: "(A <= wp act B) = (act `` A <= B)"
    36 theorem wp_iff: "(A <= wp act B) = (act `` A <= B)"
    37 by (force simp add: wp_def) 
    37 by (force simp add: wp_def) 
    38 
    38 
    39 text{*This lemma is a good deal more intuitive than the definition!*}
    39 text\<open>This lemma is a good deal more intuitive than the definition!\<close>
    40 lemma in_wp_iff: "(a \<in> wp act B) = (\<forall>x. (a,x) \<in> act --> x \<in> B)"
    40 lemma in_wp_iff: "(a \<in> wp act B) = (\<forall>x. (a,x) \<in> act --> x \<in> B)"
    41 by (simp add: wp_def, blast)
    41 by (simp add: wp_def, blast)
    42 
    42 
    43 lemma Compl_Domain_subset_wp: "- (Domain act) \<subseteq> wp act B"
    43 lemma Compl_Domain_subset_wp: "- (Domain act) \<subseteq> wp act B"
    44 by (force simp add: wp_def) 
    44 by (force simp add: wp_def) 
    45 
    45 
    46 lemma wp_empty [simp]: "wp act {} = - (Domain act)"
    46 lemma wp_empty [simp]: "wp act {} = - (Domain act)"
    47 by (force simp add: wp_def)
    47 by (force simp add: wp_def)
    48 
    48 
    49 text{*The identity relation is the skip action*}
    49 text\<open>The identity relation is the skip action\<close>
    50 lemma wp_Id [simp]: "wp Id B = B"
    50 lemma wp_Id [simp]: "wp Id B = B"
    51 by (simp add: wp_def) 
    51 by (simp add: wp_def) 
    52 
    52 
    53 lemma wp_totalize_act:
    53 lemma wp_totalize_act:
    54      "wp (totalize_act act) B = (wp act B \<inter> Domain act) \<union> (B - Domain act)"
    54      "wp (totalize_act act) B = (wp act B \<inter> Domain act) \<union> (B - Domain act)"
    58 by (force simp add: awp_def wp_def)
    58 by (force simp add: awp_def wp_def)
    59 
    59 
    60 lemma awp_Int_eq: "awp F (A\<inter>B) = awp F A \<inter> awp F B"
    60 lemma awp_Int_eq: "awp F (A\<inter>B) = awp F A \<inter> awp F B"
    61 by (simp add: awp_def wp_def, blast) 
    61 by (simp add: awp_def wp_def, blast) 
    62 
    62 
    63 text{*The fundamental theorem for awp*}
    63 text\<open>The fundamental theorem for awp\<close>
    64 theorem awp_iff_constrains: "(A <= awp F B) = (F \<in> A co B)"
    64 theorem awp_iff_constrains: "(A <= awp F B) = (F \<in> A co B)"
    65 by (simp add: awp_def constrains_def wp_iff INT_subset_iff) 
    65 by (simp add: awp_def constrains_def wp_iff INT_subset_iff) 
    66 
    66 
    67 lemma awp_iff_stable: "(A \<subseteq> awp F A) = (F \<in> stable A)"
    67 lemma awp_iff_stable: "(A \<subseteq> awp F A) = (F \<in> stable A)"
    68 by (simp add: awp_iff_constrains stable_def) 
    68 by (simp add: awp_iff_constrains stable_def) 
    86 done
    86 done
    87 
    87 
    88 lemma wens_Id [simp]: "wens F Id B = B"
    88 lemma wens_Id [simp]: "wens F Id B = B"
    89 by (simp add: wens_def gfp_def wp_def awp_def, blast)
    89 by (simp add: wens_def gfp_def wp_def awp_def, blast)
    90 
    90 
    91 text{*These two theorems justify the claim that @{term wens} returns the
    91 text\<open>These two theorems justify the claim that @{term wens} returns the
    92 weakest assertion satisfying the ensures property*}
    92 weakest assertion satisfying the ensures property\<close>
    93 lemma ensures_imp_wens: "F \<in> A ensures B ==> \<exists>act \<in> Acts F. A \<subseteq> wens F act B"
    93 lemma ensures_imp_wens: "F \<in> A ensures B ==> \<exists>act \<in> Acts F. A \<subseteq> wens F act B"
    94 apply (simp add: wens_def ensures_def transient_def, clarify) 
    94 apply (simp add: wens_def ensures_def transient_def, clarify) 
    95 apply (rule rev_bexI, assumption) 
    95 apply (rule rev_bexI, assumption) 
    96 apply (rule gfp_upperbound)
    96 apply (rule gfp_upperbound)
    97 apply (simp add: constrains_def awp_def wp_def, blast)
    97 apply (simp add: constrains_def awp_def wp_def, blast)
    99 
    99 
   100 lemma wens_ensures: "act \<in> Acts F ==> F \<in> (wens F act B) ensures B"
   100 lemma wens_ensures: "act \<in> Acts F ==> F \<in> (wens F act B) ensures B"
   101 by (simp add: wens_def gfp_def constrains_def awp_def wp_def
   101 by (simp add: wens_def gfp_def constrains_def awp_def wp_def
   102               ensures_def transient_def, blast)
   102               ensures_def transient_def, blast)
   103 
   103 
   104 text{*These two results constitute assertion (4.13) of the thesis*}
   104 text\<open>These two results constitute assertion (4.13) of the thesis\<close>
   105 lemma wens_mono: "(A \<subseteq> B) ==> wens F act A \<subseteq> wens F act B"
   105 lemma wens_mono: "(A \<subseteq> B) ==> wens F act A \<subseteq> wens F act B"
   106 apply (simp add: wens_def wp_def awp_def) 
   106 apply (simp add: wens_def wp_def awp_def) 
   107 apply (rule gfp_mono, blast) 
   107 apply (rule gfp_mono, blast) 
   108 done
   108 done
   109 
   109 
   110 lemma wens_weakening: "B \<subseteq> wens F act B"
   110 lemma wens_weakening: "B \<subseteq> wens F act B"
   111 by (simp add: wens_def gfp_def, blast)
   111 by (simp add: wens_def gfp_def, blast)
   112 
   112 
   113 text{*Assertion (6), or 4.16 in the thesis*}
   113 text\<open>Assertion (6), or 4.16 in the thesis\<close>
   114 lemma subset_wens: "A-B \<subseteq> wp act B \<inter> awp F (B \<union> A) ==> A \<subseteq> wens F act B" 
   114 lemma subset_wens: "A-B \<subseteq> wp act B \<inter> awp F (B \<union> A) ==> A \<subseteq> wens F act B" 
   115 apply (simp add: wens_def wp_def awp_def) 
   115 apply (simp add: wens_def wp_def awp_def) 
   116 apply (rule gfp_upperbound, blast) 
   116 apply (rule gfp_upperbound, blast) 
   117 done
   117 done
   118 
   118 
   119 text{*Assertion 4.17 in the thesis*}
   119 text\<open>Assertion 4.17 in the thesis\<close>
   120 lemma Diff_wens_constrains: "F \<in> (wens F act A - A) co wens F act A"
   120 lemma Diff_wens_constrains: "F \<in> (wens F act A - A) co wens F act A"
   121 by (simp add: wens_def gfp_def wp_def awp_def constrains_def, blast)
   121 by (simp add: wens_def gfp_def wp_def awp_def constrains_def, blast)
   122   --{*Proved instantly, yet remarkably fragile. If @{text Un_subset_iff}
   122   \<comment>\<open>Proved instantly, yet remarkably fragile. If \<open>Un_subset_iff\<close>
   123       is declared as an iff-rule, then it's almost impossible to prove. 
   123       is declared as an iff-rule, then it's almost impossible to prove. 
   124       One proof is via @{text meson} after expanding all definitions, but it's
   124       One proof is via \<open>meson\<close> after expanding all definitions, but it's
   125       slow!*}
   125       slow!\<close>
   126 
   126 
   127 text{*Assertion (7): 4.18 in the thesis.  NOTE that many of these results
   127 text\<open>Assertion (7): 4.18 in the thesis.  NOTE that many of these results
   128 hold for an arbitrary action.  We often do not require @{term "act \<in> Acts F"}*}
   128 hold for an arbitrary action.  We often do not require @{term "act \<in> Acts F"}\<close>
   129 lemma stable_wens: "F \<in> stable A ==> F \<in> stable (wens F act A)"
   129 lemma stable_wens: "F \<in> stable A ==> F \<in> stable (wens F act A)"
   130 apply (simp add: stable_def)
   130 apply (simp add: stable_def)
   131 apply (drule constrains_Un [OF Diff_wens_constrains [of F act A]]) 
   131 apply (drule constrains_Un [OF Diff_wens_constrains [of F act A]]) 
   132 apply (simp add: Un_Int_distrib2 Compl_partition2) 
   132 apply (simp add: Un_Int_distrib2 Compl_partition2) 
   133 apply (erule constrains_weaken, blast) 
   133 apply (erule constrains_weaken, blast) 
   134 apply (simp add: wens_weakening)
   134 apply (simp add: wens_weakening)
   135 done
   135 done
   136 
   136 
   137 text{*Assertion 4.20 in the thesis.*}
   137 text\<open>Assertion 4.20 in the thesis.\<close>
   138 lemma wens_Int_eq_lemma:
   138 lemma wens_Int_eq_lemma:
   139       "[|T-B \<subseteq> awp F T; act \<in> Acts F|]
   139       "[|T-B \<subseteq> awp F T; act \<in> Acts F|]
   140        ==> T \<inter> wens F act B \<subseteq> wens F act (T\<inter>B)"
   140        ==> T \<inter> wens F act B \<subseteq> wens F act (T\<inter>B)"
   141 apply (rule subset_wens) 
   141 apply (rule subset_wens) 
   142 apply (rule_tac P="\<lambda>x. f x \<subseteq> b" for f b in ssubst [OF wens_unfold])
   142 apply (rule_tac P="\<lambda>x. f x \<subseteq> b" for f b in ssubst [OF wens_unfold])
   143 apply (simp add: wp_def awp_def, blast)
   143 apply (simp add: wp_def awp_def, blast)
   144 done
   144 done
   145 
   145 
   146 text{*Assertion (8): 4.21 in the thesis. Here we indeed require
   146 text\<open>Assertion (8): 4.21 in the thesis. Here we indeed require
   147       @{term "act \<in> Acts F"}*}
   147       @{term "act \<in> Acts F"}\<close>
   148 lemma wens_Int_eq:
   148 lemma wens_Int_eq:
   149       "[|T-B \<subseteq> awp F T; act \<in> Acts F|]
   149       "[|T-B \<subseteq> awp F T; act \<in> Acts F|]
   150        ==> T \<inter> wens F act B = T \<inter> wens F act (T\<inter>B)"
   150        ==> T \<inter> wens F act B = T \<inter> wens F act (T\<inter>B)"
   151 apply (rule equalityI)
   151 apply (rule equalityI)
   152  apply (simp_all add: Int_lower1) 
   152  apply (simp_all add: Int_lower1) 
   153  apply (rule wens_Int_eq_lemma, assumption+) 
   153  apply (rule wens_Int_eq_lemma, assumption+) 
   154 apply (rule subset_trans [OF _ wens_mono [of "T\<inter>B" B]], auto) 
   154 apply (rule subset_trans [OF _ wens_mono [of "T\<inter>B" B]], auto) 
   155 done
   155 done
   156 
   156 
   157 
   157 
   158 subsection{*Defining the Weakest Ensures Set*}
   158 subsection\<open>Defining the Weakest Ensures Set\<close>
   159 
   159 
   160 inductive_set
   160 inductive_set
   161   wens_set :: "['a program, 'a set] => 'a set set"
   161   wens_set :: "['a program, 'a set] => 'a set set"
   162   for F :: "'a program" and B :: "'a set"
   162   for F :: "'a program" and B :: "'a set"
   163 where
   163 where
   196 apply (clarsimp dest!: bchoice simp: ball_conj_distrib Bex_def) 
   196 apply (clarsimp dest!: bchoice simp: ball_conj_distrib Bex_def) 
   197 apply (rule_tac x = "\<Union>{Z. \<exists>U\<in>S. Z = f U}" in exI)
   197 apply (rule_tac x = "\<Union>{Z. \<exists>U\<in>S. Z = f U}" in exI)
   198 apply (blast intro: wens_set.Union) 
   198 apply (blast intro: wens_set.Union) 
   199 done
   199 done
   200 
   200 
   201 text{*Assertion (9): 4.27 in the thesis.*}
   201 text\<open>Assertion (9): 4.27 in the thesis.\<close>
   202 lemma leadsTo_iff_wens_set: "(F \<in> A leadsTo B) = (\<exists>C \<in> wens_set F B. A \<subseteq> C)"
   202 lemma leadsTo_iff_wens_set: "(F \<in> A leadsTo B) = (\<exists>C \<in> wens_set F B. A \<subseteq> C)"
   203 by (blast intro: leadsTo_imp_wens_set leadsTo_weaken_L wens_set_imp_leadsTo) 
   203 by (blast intro: leadsTo_imp_wens_set leadsTo_weaken_L wens_set_imp_leadsTo) 
   204 
   204 
   205 text{*This is the result that requires the definition of @{term wens_set} to
   205 text\<open>This is the result that requires the definition of @{term wens_set} to
   206   require @{term W} to be non-empty in the Unio case, for otherwise we should
   206   require @{term W} to be non-empty in the Unio case, for otherwise we should
   207   always have @{term "{} \<in> wens_set F B"}.*}
   207   always have @{term "{} \<in> wens_set F B"}.\<close>
   208 lemma wens_set_imp_subset: "A \<in> wens_set F B ==> B \<subseteq> A"
   208 lemma wens_set_imp_subset: "A \<in> wens_set F B ==> B \<subseteq> A"
   209 apply (erule wens_set.induct) 
   209 apply (erule wens_set.induct) 
   210   apply (blast intro: wens_weakening [THEN subsetD])+
   210   apply (blast intro: wens_weakening [THEN subsetD])+
   211 done
   211 done
   212 
   212 
   213 
   213 
   214 subsection{*Properties Involving Program Union*}
   214 subsection\<open>Properties Involving Program Union\<close>
   215 
   215 
   216 text{*Assertion (4.30) of thesis, reoriented*}
   216 text\<open>Assertion (4.30) of thesis, reoriented\<close>
   217 lemma awp_Join_eq: "awp (F\<squnion>G) B = awp F B \<inter> awp G B"
   217 lemma awp_Join_eq: "awp (F\<squnion>G) B = awp F B \<inter> awp G B"
   218 by (simp add: awp_def wp_def, blast)
   218 by (simp add: awp_def wp_def, blast)
   219 
   219 
   220 lemma wens_subset: "wens F act B - B \<subseteq> wp act B \<inter> awp F (B \<union> wens F act B)"
   220 lemma wens_subset: "wens F act B - B \<subseteq> wp act B \<inter> awp F (B \<union> wens F act B)"
   221 by (subst wens_unfold, fast) 
   221 by (subst wens_unfold, fast) 
   222 
   222 
   223 text{*Assertion (4.31)*}
   223 text\<open>Assertion (4.31)\<close>
   224 lemma subset_wens_Join:
   224 lemma subset_wens_Join:
   225       "[|A = T \<inter> wens F act B;  T-B \<subseteq> awp F T; A-B \<subseteq> awp G (A \<union> B)|] 
   225       "[|A = T \<inter> wens F act B;  T-B \<subseteq> awp F T; A-B \<subseteq> awp G (A \<union> B)|] 
   226        ==> A \<subseteq> wens (F\<squnion>G) act B"
   226        ==> A \<subseteq> wens (F\<squnion>G) act B"
   227 apply (subgoal_tac "(T \<inter> wens F act B) - B \<subseteq> 
   227 apply (subgoal_tac "(T \<inter> wens F act B) - B \<subseteq> 
   228                     wp act B \<inter> awp F (B \<union> wens F act B) \<inter> awp F T") 
   228                     wp act B \<inter> awp F (B \<union> wens F act B) \<inter> awp F T") 
   230  apply (simp add: awp_Join_eq awp_Int_eq Un_commute)
   230  apply (simp add: awp_Join_eq awp_Int_eq Un_commute)
   231  apply (simp add: awp_def wp_def, blast) 
   231  apply (simp add: awp_def wp_def, blast) 
   232 apply (insert wens_subset [of F act B], blast) 
   232 apply (insert wens_subset [of F act B], blast) 
   233 done
   233 done
   234 
   234 
   235 text{*Assertion (4.32)*}
   235 text\<open>Assertion (4.32)\<close>
   236 lemma wens_Join_subset: "wens (F\<squnion>G) act B \<subseteq> wens F act B"
   236 lemma wens_Join_subset: "wens (F\<squnion>G) act B \<subseteq> wens F act B"
   237 apply (simp add: wens_def) 
   237 apply (simp add: wens_def) 
   238 apply (rule gfp_mono)
   238 apply (rule gfp_mono)
   239 apply (auto simp add: awp_Join_eq)  
   239 apply (auto simp add: awp_Join_eq)  
   240 done
   240 done
   241 
   241 
   242 text{*Lemma, because the inductive step is just too messy.*}
   242 text\<open>Lemma, because the inductive step is just too messy.\<close>
   243 lemma wens_Union_inductive_step:
   243 lemma wens_Union_inductive_step:
   244   assumes awpF: "T-B \<subseteq> awp F T"
   244   assumes awpF: "T-B \<subseteq> awp F T"
   245       and awpG: "!!X. X \<in> wens_set F B ==> (T\<inter>X) - B \<subseteq> awp G (T\<inter>X)"
   245       and awpG: "!!X. X \<in> wens_set F B ==> (T\<inter>X) - B \<subseteq> awp G (T\<inter>X)"
   246   shows "[|X \<in> wens_set F B; act \<in> Acts F; Y \<subseteq> X; T\<inter>X = T\<inter>Y|]
   246   shows "[|X \<in> wens_set F B; act \<in> Acts F; Y \<subseteq> X; T\<inter>X = T\<inter>Y|]
   247          ==> wens (F\<squnion>G) act Y \<subseteq> wens F act X \<and>
   247          ==> wens (F\<squnion>G) act Y \<subseteq> wens F act X \<and>
   270   assumes awpF: "T-B \<subseteq> awp F T"
   270   assumes awpF: "T-B \<subseteq> awp F T"
   271       and awpG: "!!X. X \<in> wens_set F B ==> (T\<inter>X) - B \<subseteq> awp G (T\<inter>X)"
   271       and awpG: "!!X. X \<in> wens_set F B ==> (T\<inter>X) - B \<subseteq> awp G (T\<inter>X)"
   272       and major: "X \<in> wens_set F B"
   272       and major: "X \<in> wens_set F B"
   273   shows "\<exists>Y \<in> wens_set (F\<squnion>G) B. Y \<subseteq> X & T\<inter>X = T\<inter>Y"
   273   shows "\<exists>Y \<in> wens_set (F\<squnion>G) B. Y \<subseteq> X & T\<inter>X = T\<inter>Y"
   274 apply (rule wens_set.induct [OF major])
   274 apply (rule wens_set.induct [OF major])
   275   txt{*Basis: trivial*}
   275   txt\<open>Basis: trivial\<close>
   276   apply (blast intro: wens_set.Basis)
   276   apply (blast intro: wens_set.Basis)
   277  txt{*Inductive step*}
   277  txt\<open>Inductive step\<close>
   278  apply clarify 
   278  apply clarify 
   279  apply (rule_tac x = "wens (F\<squnion>G) act Y" in rev_bexI)
   279  apply (rule_tac x = "wens (F\<squnion>G) act Y" in rev_bexI)
   280   apply (force intro: wens_set.Wens)
   280   apply (force intro: wens_set.Wens)
   281  apply (simp add: wens_Union_inductive_step [OF awpF awpG]) 
   281  apply (simp add: wens_Union_inductive_step [OF awpF awpG]) 
   282 txt{*Union: by Axiom of Choice*}
   282 txt\<open>Union: by Axiom of Choice\<close>
   283 apply (simp add: ball_conj_distrib Bex_def) 
   283 apply (simp add: ball_conj_distrib Bex_def) 
   284 apply (clarify dest!: bchoice) 
   284 apply (clarify dest!: bchoice) 
   285 apply (rule_tac x = "\<Union>{Z. \<exists>U\<in>W. Z = f U}" in exI)
   285 apply (rule_tac x = "\<Union>{Z. \<exists>U\<in>W. Z = f U}" in exI)
   286 apply (blast intro: wens_set.Union) 
   286 apply (blast intro: wens_set.Union) 
   287 done
   287 done
   297   apply (erule awpG, assumption)
   297   apply (erule awpG, assumption)
   298 apply (blast intro: wens_set_imp_leadsTo [THEN leadsTo_weaken_L])  
   298 apply (blast intro: wens_set_imp_leadsTo [THEN leadsTo_weaken_L])  
   299 done
   299 done
   300 
   300 
   301 
   301 
   302 subsection {*The Set @{term "wens_set F B"} for a Single-Assignment Program*}
   302 subsection \<open>The Set @{term "wens_set F B"} for a Single-Assignment Program\<close>
   303 text{*Thesis Section 4.3.3*}
   303 text\<open>Thesis Section 4.3.3\<close>
   304 
   304 
   305 text{*We start by proving laws about single-assignment programs*}
   305 text\<open>We start by proving laws about single-assignment programs\<close>
   306 lemma awp_single_eq [simp]:
   306 lemma awp_single_eq [simp]:
   307      "awp (mk_program (init, {act}, allowed)) B = B \<inter> wp act B"
   307      "awp (mk_program (init, {act}, allowed)) B = B \<inter> wp act B"
   308 by (force simp add: awp_def wp_def) 
   308 by (force simp add: awp_def wp_def) 
   309 
   309 
   310 lemma wp_Un_subset: "wp act A \<union> wp act B \<subseteq> wp act (A \<union> B)"
   310 lemma wp_Un_subset: "wp act A \<union> wp act B \<subseteq> wp act (A \<union> B)"
   330 lemma wens_single_eq:
   330 lemma wens_single_eq:
   331      "wens (mk_program (init, {act}, allowed)) act B = B \<union> wp act B"
   331      "wens (mk_program (init, {act}, allowed)) act B = B \<union> wp act B"
   332 by (simp add: wens_def gfp_def wp_def, blast)
   332 by (simp add: wens_def gfp_def wp_def, blast)
   333 
   333 
   334 
   334 
   335 text{*Next, we express the @{term "wens_set"} for single-assignment programs*}
   335 text\<open>Next, we express the @{term "wens_set"} for single-assignment programs\<close>
   336 
   336 
   337 definition wens_single_finite :: "[('a*'a) set, 'a set, nat] => 'a set" where  
   337 definition wens_single_finite :: "[('a*'a) set, 'a set, nat] => 'a set" where  
   338     "wens_single_finite act B k == \<Union>i \<in> atMost k. (wp act ^^ i) B"
   338     "wens_single_finite act B k == \<Union>i \<in> atMost k. (wp act ^^ i) B"
   339 
   339 
   340 definition wens_single :: "[('a*'a) set, 'a set] => 'a set" where
   340 definition wens_single :: "[('a*'a) set, 'a set] => 'a set" where
   414  prefer 2 apply blast
   414  prefer 2 apply blast
   415 apply (subst wens_single_finite_eq_Union)
   415 apply (subst wens_single_finite_eq_Union)
   416 apply (simp add: atMost_Suc, blast)
   416 apply (simp add: atMost_Suc, blast)
   417 done
   417 done
   418 
   418 
   419 text{*lemma for Union case*}
   419 text\<open>lemma for Union case\<close>
   420 lemma Union_eq_wens_single:
   420 lemma Union_eq_wens_single:
   421       "\<lbrakk>\<forall>k. \<not> W \<subseteq> wens_single_finite act B ` {..k};
   421       "\<lbrakk>\<forall>k. \<not> W \<subseteq> wens_single_finite act B ` {..k};
   422         W \<subseteq> insert (wens_single act B)
   422         W \<subseteq> insert (wens_single act B)
   423             (range (wens_single_finite act B))\<rbrakk>
   423             (range (wens_single_finite act B))\<rbrakk>
   424        \<Longrightarrow> \<Union>W = wens_single act B"
   424        \<Longrightarrow> \<Union>W = wens_single act B"
   437       "single_valued act
   437       "single_valued act
   438        ==> wens_set (mk_program (init, {act}, allowed)) B \<subseteq> 
   438        ==> wens_set (mk_program (init, {act}, allowed)) B \<subseteq> 
   439            insert (wens_single act B) (range (wens_single_finite act B))"
   439            insert (wens_single act B) (range (wens_single_finite act B))"
   440 apply (rule subsetI)  
   440 apply (rule subsetI)  
   441 apply (erule wens_set.induct)
   441 apply (erule wens_set.induct)
   442   txt{*Basis*} 
   442   txt\<open>Basis\<close> 
   443   apply (fastforce simp add: wens_single_finite_def)
   443   apply (fastforce simp add: wens_single_finite_def)
   444  txt{*Wens inductive step*}
   444  txt\<open>Wens inductive step\<close>
   445  apply (case_tac "acta = Id", simp)
   445  apply (case_tac "acta = Id", simp)
   446  apply (simp add: wens_single_eq)
   446  apply (simp add: wens_single_eq)
   447  apply (elim disjE)
   447  apply (elim disjE)
   448  apply (simp add: wens_single_Un_eq)
   448  apply (simp add: wens_single_Un_eq)
   449  apply (force simp add: wens_single_finite_Un_eq)
   449  apply (force simp add: wens_single_finite_Un_eq)
   450 txt{*Union inductive step*}
   450 txt\<open>Union inductive step\<close>
   451 apply (case_tac "\<exists>k. W \<subseteq> wens_single_finite act B ` (atMost k)")
   451 apply (case_tac "\<exists>k. W \<subseteq> wens_single_finite act B ` (atMost k)")
   452  apply (blast dest!: subset_wens_single_finite, simp) 
   452  apply (blast dest!: subset_wens_single_finite, simp) 
   453 apply (rule disjI1 [OF Union_eq_wens_single], blast+)
   453 apply (rule disjI1 [OF Union_eq_wens_single], blast+)
   454 done
   454 done
   455 
   455 
   469            wens_set (mk_program (init, {act}, allowed)) B"
   469            wens_set (mk_program (init, {act}, allowed)) B"
   470 apply (simp add: image_def wens_single_eq_Union) 
   470 apply (simp add: image_def wens_single_eq_Union) 
   471 apply (blast intro: wens_set.Union wens_single_finite_in_wens_set)
   471 apply (blast intro: wens_set.Union wens_single_finite_in_wens_set)
   472 done
   472 done
   473 
   473 
   474 text{*Theorem (4.29)*}
   474 text\<open>Theorem (4.29)\<close>
   475 theorem wens_set_single_eq:
   475 theorem wens_set_single_eq:
   476      "[|F = mk_program (init, {act}, allowed); single_valued act|]
   476      "[|F = mk_program (init, {act}, allowed); single_valued act|]
   477       ==> wens_set F B =
   477       ==> wens_set F B =
   478           insert (wens_single act B) (range (wens_single_finite act B))"
   478           insert (wens_single act B) (range (wens_single_finite act B))"
   479 apply (rule equalityI)
   479 apply (rule equalityI)
   480  apply (simp add: wens_set_subset_single) 
   480  apply (simp add: wens_set_subset_single) 
   481 apply (erule ssubst, erule single_subset_wens_set) 
   481 apply (erule ssubst, erule single_subset_wens_set) 
   482 done
   482 done
   483 
   483 
   484 text{*Generalizing Misra's Fixed Point Union Theorem (4.41)*}
   484 text\<open>Generalizing Misra's Fixed Point Union Theorem (4.41)\<close>
   485 
   485 
   486 lemma fp_leadsTo_Join:
   486 lemma fp_leadsTo_Join:
   487     "[|T-B \<subseteq> awp F T; T-B \<subseteq> FP G; F \<in> A leadsTo B|] ==> F\<squnion>G \<in> T\<inter>A leadsTo B"
   487     "[|T-B \<subseteq> awp F T; T-B \<subseteq> FP G; F \<in> A leadsTo B|] ==> F\<squnion>G \<in> T\<inter>A leadsTo B"
   488 apply (rule leadsTo_Join, assumption, blast)
   488 apply (rule leadsTo_Join, assumption, blast)
   489 apply (simp add: FP_def awp_iff_constrains stable_def constrains_def, blast) 
   489 apply (simp add: FP_def awp_iff_constrains stable_def constrains_def, blast)