Implementation.thy
changeset 178 da27bece9575
parent 136 fb3f52fe99d1
child 179 f9e6c4166476
equal deleted inserted replaced
177:abe117821c32 178:da27bece9575
     1 theory Implementation
     1 theory Implementation
     2 imports PIPBasics
     2 imports PIPBasics
     3 begin
     3 begin
     4 
     4 
       
     5 
       
     6 (*
       
     7   The use of dependants has been abandoned. Through a series of lemma 
       
     8   named xxx_alt_def, lemma originally expressed using dependants 
       
     9   is now expressed in terms of RAG, tRAG and tG.
       
    10 *)
       
    11 
     5 text {*
    12 text {*
     6 
    13 
     7   This file contains lemmas used to guide the recalculation of current
    14   This file contains lemmas used to guide the recalculation of current
     8   precedence after every step of execution (or system operation, or event),
    15   precedence after every step of execution (or system operation, or event),
     9   which is the most tricky part in the implementation of PIP.
    16   which is the most tricky part in the implementation of PIP.
    10 
    17 
    11   Following convention, lemmas are grouped into locales corresponding to
    18   Following convention, lemmas are grouped into locales corresponding to
    12   system operations, each explained in a separate section. *}
    19   system operations, each explained in a separate section. To understand the relevant 
    13 
    20   materials, one needs some acquaintance with locales, which are 
    14 text {*
    21   used to as contexts for lemmas to situate, where lemmas with the same assumptions
    15   The following two lemmas are general about any valid system state, 
    22   are grouped under the same locale.
    16   but are used in the derivation in more specific system operations. 
    23 
    17 *}
    24   Locale @{text "valid_trace s"} assumes that @{text "s"} is a valid trace (or state)
       
    25   of PIP. Lemmas talking about general properties of valid states can be put under this 
       
    26   locale. The locale @{text "valid_trace_e s e"} is an extension of @{text valid_trace}
       
    27   by introducing an event @{text e} and assuming @{text "e#s"} is also valid state. 
       
    28   The purpose of @{text valid_trace_e} is to set a context to investigate 
       
    29   one step execution of PIP, where @{text e} is a fixed but arbitrary
       
    30   action legitimate to happen under state @{text "s"}. General Properties about 
       
    31   one step action of PIP are grouped under this locale.
       
    32 
       
    33   @{text "valid_trace_e"} is further extended to accommodate specific actions. For example,
       
    34   @{text "valid_trace_create s e th prio"} further assumes that the 
       
    35   @{text "e"} action is @{text "Create th prio"}, and 
       
    36   @{text "valid_trace_p s e th cs"} assumes that @{text "e"} is @{text "P th cs"}, etc.
       
    37 
       
    38   Since the recalculation of current precedence happens only when certain actions 
       
    39   are taken, it is natural to put the lemmas about recalculation under the respective 
       
    40   locales. In the following, each section corresponds one particular action of PIP, which,
       
    41   in turn, is developed under the locale corresponding to the specific action.
       
    42 
       
    43   By @{text cp_alt_def3}, the @{text cp}-value of one thread @{text th} is determined 
       
    44   uniquely by static precedences of threads in its @{text "RAG"}-subtree 
       
    45   (or @{text tRAG}-subtree, @{text "tG"}-subtree). Because of this, the decision where 
       
    46   recalculation is needed is based on the change of @{text RAG} (@{text tRAG} or @{text tG})
       
    47   as well the precedence of threads. Since most of PIP actions (except the @{text Set}-operation) 
       
    48   only changes the formation of @{text RAG}, therefore, for non-@{text Set} operations,
       
    49   if the change of @{text RAG} does not affect the subtree
       
    50   of one thread, its @{text cp}-value may not change. 
       
    51 
       
    52   In the following, the section corresponding to non-@{text Set} operations 
       
    53   usually contain lemmas showing the subtrees of certain kind of threads are 
       
    54   not changed. The proof of such lemmas is obvious based on the lemmas about the
       
    55   change of @{text RAG}, which have already been derived in theory @{text PIPBasics}
       
    56   all under the name @{text "RAG_es"} in the locale corresponding to different PIP 
       
    57   operations.
       
    58 *}
       
    59 
       
    60 section {* The local recalculation principle for @{text cp}-value *}
       
    61 
       
    62 definition "cprecs Ths s = cp s ` Ths"
    18 
    63 
    19 context valid_trace
    64 context valid_trace
    20 begin
    65 begin
    21 
    66 
    22 lemma readys_root:
    67 text {*
    23   assumes "th \<in> readys s"
    68   To minimize the cost of the recalculation, we derived the following localized alternative 
    24   shows "root (RAG s) (Th th)"
    69   definition of @{term cp}:
    25   unfolding root_def ancestors_def
    70 *}
    26   using readys_RAG assms
    71 
    27 by (metis Collect_empty_eq Domain.DomainI trancl_domain)
    72 lemma cp_rec_tG:
    28 
    73   "cp s th = Max (preceds {th} s \<union> cprecs (children (tG s) th) s)"
    29 lemma readys_in_no_subtree:
    74 proof -
    30   assumes "th \<in> readys s"
    75   have [simp]: "(cp s \<circ> the_thread \<circ> Th) = cp s" by (rule ext, simp)
    31   and "th' \<noteq> th"
    76   have [simp]: "(cp s \<circ> the_thread) ` children (tRAG s) (Th th) = 
    32   shows "Th th \<notin> subtree (RAG s) (Th th')" 
    77                 cp s ` children (tG s) th"
    33 proof
    78                   apply (unfold tRAG_def_tG) 
    34    assume "Th th \<in> subtree (RAG s) (Th th')"
    79                   apply (subst fmap_children)
    35    thus False
    80                   apply (rule injI, simp)
    36    proof(cases rule:subtreeE)
    81                   by (unfold image_comp, simp)
    37       case 1
    82   have [simp]: "preceds {th} s = {the_preced s th}"
    38       with assms show ?thesis by auto
    83     by (unfold the_preced_def, simp)
    39    next
    84   show ?thesis 
    40       case 2
    85     by (unfold cp_rec cprecs_def, simp add:the_preced_def)
    41       with readys_root[OF assms(1)]
    86 qed    
    42       show ?thesis by (auto simp:root_def)
    87 
    43    qed
    88 text {*
    44 qed
    89   According to this lemma, @{text cp}-value of one thread can be calculated by calling recursively 
       
    90   the @{text cp} function on its @{text tG}-children. However, one thing to be noted is that
       
    91   the lemma also means the recursive call needs not to descend into lower levels if the
       
    92   @{text "cp"}-value of one child is not changed. In this way, the recalculation can be {\em localized}
       
    93   to those thread with changed @{text cp}-value. This is the reason why this lemma
       
    94   is called a {\em localized lemma}.
       
    95 *}
    45 
    96 
    46 end
    97 end
    47 
    98 
    48 section {* The @{term Set} operation *}
    99 section {* The @{term Set} operation *}
    49 
   100 
    71   using assms
   122   using assms
    72   by (unfold the_preced_def, intro eq_preced, simp)
   123   by (unfold the_preced_def, intro eq_preced, simp)
    73 
   124 
    74 
   125 
    75 text {* (* ddd *)
   126 text {* (* ddd *)
    76   Th following lemma @{text "eq_cp_pre"} says that the priority change of @{text "th"}
   127   According to @{thm RAG_es}, the @{text RAG} is not changed by @{text Set}-operation.
    77   only affects those threads, which as @{text "Th th"} in their sub-trees.
   128   Moreover, because @{text th} is the only thread with precedence changed by @{text Set}, 
    78   
   129   for any subtree, if it does not contain @{text th}, there will be no precedence change inside
    79   The proof of this lemma is simplified by using the alternative definition 
   130   the subtree, which means the @{text cp}-value of the root thread is not changed. 
    80   of @{text "cp"}. 
   131   This means that the @{text "cp"}-value of one thread needs to be recalculated only
       
   132   when the subtree rooted by the threads contains @{text "th"}.
       
   133  
       
   134   This argument is encapsulated in the following lemma:
    81 *}
   135 *}
    82 
   136 
    83 lemma eq_cp_pre:
   137 lemma eq_cp_pre:
    84   assumes nd: "Th th \<notin> subtree (RAG s) (Th th')"
   138   assumes nd: "Th th \<notin> subtree (RAG s) (Th th')"
    85   shows "cp (e#s) th' = cp s th'"
   139   shows "cp (e#s) th' = cp s th'"
   108   qed
   162   qed
   109   thus ?thesis by (simp add:cp_alt_def)
   163   thus ?thesis by (simp add:cp_alt_def)
   110 qed
   164 qed
   111 
   165 
   112 text {*
   166 text {*
   113   The following lemma shows that @{term "th"} is not in the 
   167   However, the following lemma shows that @{term "th"} is not in the 
   114   sub-tree of any other thread. 
   168   subtree of any thread except itself. 
   115 *}
   169 *}
   116 lemma th_in_no_subtree:
   170 lemma th_in_no_subtree:
   117   assumes "th' \<noteq> th"
   171   assumes "th' \<noteq> th"
   118   shows "Th th \<notin> subtree (RAG s) (Th th')"
   172   shows "Th th \<notin> subtree (RAG s) (Th th')"
   119 proof -
   173 proof -
   120   from readys_in_no_subtree[OF th_ready_s assms(1)]
   174   from readys_in_no_subtree[OF th_ready_s assms(1)]
   121   show ?thesis by blast
   175   show ?thesis by blast
   122 qed
   176 qed
   123 
   177 
   124 text {* 
   178 text {* 
   125   By combining @{thm "eq_cp_pre"} and @{thm "th_in_no_subtree"}, 
   179   Combining the above two lemmas, it is concluded that the 
   126   it is obvious that the change of priority only affects the @{text "cp"}-value 
   180   recalculation of @{text "cp"}-value is needed only on @{text th}.
   127   of the initiating thread @{text "th"}.
   181 *}
   128 *}
   182 
   129 lemma eq_cp:
   183 lemma eq_cp:
   130   assumes "th' \<noteq> th"
   184   assumes "th' \<noteq> th"
   131   shows "cp (e#s) th' = cp s th'"
   185   shows "cp (e#s) th' = cp s th'"
   132   by (rule eq_cp_pre[OF th_in_no_subtree[OF assms]])
   186   by (rule eq_cp_pre[OF th_in_no_subtree[OF assms]])
   133 
   187 
       
   188 text {* 
       
   189   Under the local recalculation principle @{thm cp_rec_tG}, 
       
   190   @{thm eq_cp} also means the recalculation of @{text cp} for @{text th}
       
   191   can be done locally by inspecting only @{text th} and its children.
       
   192 *}
       
   193 
   134 end
   194 end
   135 
   195 
   136 section {* The @{term V} operation *}
   196 section {* The @{term V} operation *}
   137 
   197 
   138 text {*
   198 text {*
   139   The following @{text "step_v_cps"} is the locale for @{text "V"}-operation.
   199   The following locale @{text "valid_trace_v"} is the locale for @{text "V"}-operation in 
       
   200   general. The recalculation of @{text cp}-value needs to consider two more sub-case, each
       
   201   encapsulated into a sub-locale of @{text "valid_trace_v"}. But first, 
       
   202   some general properties about the @{text V}-operation are derived:
   140 *}
   203 *}
   141 
   204 
   142 context valid_trace_v
   205 context valid_trace_v
   143 begin
   206 begin
   144 
   207 
       
   208 text {*
       
   209   Because @{text th} is running in state @{text s}, it does not in waiting of 
       
   210   any resource, therefore, it has no ancestor in @{text "RAG s"}:
       
   211 *}
   145 lemma ancestors_th: "ancestors (RAG s) (Th th) = {}"
   212 lemma ancestors_th: "ancestors (RAG s) (Th th) = {}"
   146 proof -
   213 proof -
   147   from readys_root[OF th_ready_s]
   214   from readys_root[OF th_ready_s]
   148   show ?thesis
   215   show ?thesis
   149   by (unfold root_def, simp)
   216   by (unfold root_def, simp)
   150 qed
   217 qed
   151 
   218 
       
   219 text {*
       
   220   Since @{text th} is holding @{text cs} (the resource to be released by this @{text V}-operation),
       
   221   the edge @{text "(Cs cs, Th th)"} represents this fact.
       
   222 *}
   152 lemma edge_of_th:
   223 lemma edge_of_th:
   153     "(Cs cs, Th th) \<in> RAG s" 
   224     "(Cs cs, Th th) \<in> RAG s" 
   154 proof -
   225 proof -
   155  from holding_th_cs_s
   226  from holding_th_cs_s
   156  show ?thesis 
   227  show ?thesis 
   157     by (unfold s_RAG_def s_holding_abv, auto)
   228     by (unfold s_RAG_def s_holding_abv, auto)
   158 qed
   229 qed
   159 
   230 
       
   231 text {*
       
   232   Since @{text cs} is held by @{text th} which has no ancestors, 
       
   233   @{text th} is the only ancestor of @{text cs}:
       
   234 *}
   160 lemma ancestors_cs: 
   235 lemma ancestors_cs: 
   161   "ancestors (RAG s) (Cs cs) = {Th th}"
   236   "ancestors (RAG s) (Cs cs) = {Th th}"
   162 proof -
   237 proof -
   163   have "ancestors (RAG s) (Cs cs) = ancestors (RAG s) (Th th)  \<union>  {Th th}"
   238   have "ancestors (RAG s) (Cs cs) = ancestors (RAG s) (Th th)  \<union>  {Th th}"
   164    by (rule forest_RAG.ancestors_accum[OF edge_of_th])
   239    by (rule forest_RAG.ancestors_accum[OF edge_of_th])
   165   from this[unfolded ancestors_th] show ?thesis by simp
   240   from this[unfolded ancestors_th] show ?thesis by simp
   166 qed
   241 qed
   167 
   242 
   168 end
   243 text {*
   169 
   244   As already said, all operations except @{text Set} may change precedence. 
   170 text {*
   245   The following lemma confirms this fact of the @{text V}-operation:
   171   The following @{text "step_v_cps_nt"} is the sub-locale for @{text "V"}-operation, 
   246 *}
   172   which represents the case when there is another thread @{text "th'"}
   247 lemma 
   173   to take over the critical resource released by the initiating thread @{text "th"}.
       
   174 *}
       
   175 
       
   176 lemma (in valid_trace_v)
       
   177   the_preced_es: "the_preced (e#s) = the_preced s"
   248   the_preced_es: "the_preced (e#s) = the_preced s"
   178 proof
   249 proof
   179   fix th'
   250   fix th'
   180   show "the_preced (e # s) th' = the_preced s th'"
   251   show "the_preced (e # s) th' = the_preced s th'"
   181     by (unfold the_preced_def preced_def is_v, simp)
   252     by (unfold the_preced_def preced_def is_v, simp)
   182 qed
   253 qed
   183 
   254 
       
   255 end
       
   256 
       
   257 
       
   258 text {*
       
   259   The following sub-locale @{text "valid_trace_v_n"} 
       
   260   deals with one of the sub-cases of @{text V}, which corresponds to the 
       
   261   situation where there is another thread @{text "taker"}
       
   262   to take over the release resource @{text cs}.
       
   263 *}
       
   264 
   184 context valid_trace_v_n
   265 context valid_trace_v_n
   185 begin
   266 begin
   186 
   267 
       
   268 text {*
       
   269   The following lemma shows the two edges in @{text "RAG s"} which 
       
   270   links @{text cs} with @{text taker} and @{text th} to form a chain. 
       
   271   The existence of this chain set the stage for the @{text V}-operation 
       
   272   in question to happen.
       
   273 *}
   187 lemma sub_RAGs': 
   274 lemma sub_RAGs': 
   188   "{(Cs cs, Th th), (Th taker, Cs cs)} \<subseteq> RAG s"
   275   "{(Cs cs, Th th), (Th taker, Cs cs)} \<subseteq> RAG s"
   189   using waiting_taker holding_th_cs_s
   276   using waiting_taker holding_th_cs_s
   190   by (unfold s_RAG_def, fold s_waiting_abv s_holding_abv, auto)
   277   by (unfold s_RAG_def, fold s_waiting_abv s_holding_abv, auto)
   191 
   278 
       
   279 text {*
       
   280   The following lemma shows that @{text taker} has only two the ancestors.
       
   281   The reason for this is very simple: The chain starting from @{text taker}
       
   282   stops at @{text th}, which, as shown by @{thm ancestors_th}, has no ancestor. 
       
   283 *}
   192 lemma ancestors_th': 
   284 lemma ancestors_th': 
   193   "ancestors (RAG s) (Th taker) = {Th th, Cs cs}" 
   285   "ancestors (RAG s) (Th taker) = {Th th, Cs cs}" 
   194 proof -
   286 proof -
   195   have "ancestors (RAG s) (Th taker) = ancestors (RAG s) (Cs cs) \<union> {Cs cs}"
   287   have "ancestors (RAG s) (Th taker) = ancestors (RAG s) (Cs cs) \<union> {Cs cs}"
   196   proof(rule  forest_RAG.ancestors_accum)
   288   proof(rule  forest_RAG.ancestors_accum)
   197     from sub_RAGs' show "(Th taker, Cs cs) \<in> RAG s" by auto
   289     from sub_RAGs' show "(Th taker, Cs cs) \<in> RAG s" by auto
   198   qed
   290   qed
   199   thus ?thesis using ancestors_th ancestors_cs by auto
   291   thus ?thesis using ancestors_th ancestors_cs by auto
   200 qed
   292 qed
   201 
   293 
       
   294 text {*
       
   295   By composing several existing results, the following lemma
       
   296   make clear the change of @{text RAG} where there is a 
       
   297   @{text taker} to take over the resource @{text cs}. 
       
   298   More specifically, the lemma says the change of @{text RAG}
       
   299   is by first removing the chain linking @{text taker}, @{text cs} and 
       
   300   @{text th} and then adding in one edge from @{text cs} to @{text taker}.
       
   301   The added edge represents acquisition of @{text cs} by @{text taker}.
       
   302 *}
   202 lemma RAG_s:
   303 lemma RAG_s:
   203   "RAG (e#s) = (RAG s - {(Cs cs, Th th), (Th taker, Cs cs)}) \<union>
   304   "RAG (e#s) = (RAG s - {(Cs cs, Th th), (Th taker, Cs cs)}) \<union>
   204                                          {(Cs cs, Th taker)}"
   305                                          {(Cs cs, Th taker)}"
   205  by (unfold RAG_es waiting_set_eq holding_set_eq, auto)
   306  by (unfold RAG_es waiting_set_eq holding_set_eq, auto)
   206 
   307 
       
   308 text {*
       
   309   The above lemma @{thm RAG_s} shows the effect of the @{text V}-operation
       
   310   on @{text RAG} is the removal of two edges followed by the addition of 
       
   311   one edge. Based on this, the following lemma will show that 
       
   312   the sub-trees of threads other than @{text th} and @{text taker} are unchanged.
       
   313   The intuition behind this is rather simple: the edges added and removed are not
       
   314   in these sub-trees. 
       
   315 
       
   316   Formally, an edge is said to be outside of a sub-tree if its
       
   317   end point is. Note that when a set of edges are represented as a binary relation, the
       
   318   set of their end points is essentially range of the relation (formally defined 
       
   319   as @{term Range}). Therefore, a set of edges (represented as a relation) 
       
   320   are outside of a sub-tree if its @{text Range}-set does not intersect 
       
   321   with the sub-tree.
       
   322 *}
       
   323 
   207 lemma subtree_kept: (* ddd *)
   324 lemma subtree_kept: (* ddd *)
   208   assumes "th1 \<notin> {th, taker}"
   325   assumes "th1 \<notin> {th, taker}"
   209   shows "subtree (RAG (e#s)) (Th th1) = 
   326   shows "subtree (RAG (e#s)) (Th th1) = 
   210                      subtree (RAG s) (Th th1)" (is "_ = ?R")
   327                      subtree (RAG s) (Th th1)" (is "_ = ?R")
   211 proof -
   328 proof -
   212   let ?RAG' = "(RAG s - {(Cs cs, Th th), (Th taker, Cs cs)})"
   329   let ?RAG' = "(RAG s - {(Cs cs, Th th), (Th taker, Cs cs)})"
   213   let ?RAG'' = "?RAG' \<union> {(Cs cs, Th taker)}"
   330   let ?RAG'' = "?RAG' \<union> {(Cs cs, Th taker)}"
       
   331   -- {* The first step is to show the deletion of edges does not change the sub-tree *}
   214   have "subtree ?RAG' (Th th1) = ?R" 
   332   have "subtree ?RAG' (Th th1) = ?R" 
   215   proof(rule subset_del_subtree_outside)
   333   proof(rule subset_del_subtree_outside)
   216     show "Range {(Cs cs, Th th), (Th taker, Cs cs)} \<inter> subtree (RAG s) (Th th1) = {}"
   334     show "Range {(Cs cs, Th th), (Th taker, Cs cs)} \<inter> subtree (RAG s) (Th th1) = {}"
   217     proof -
   335     proof -
   218       have "(Th th) \<notin> subtree (RAG s) (Th th1)"
   336       have "(Th th) \<notin> subtree (RAG s) (Th th1)"
   219       proof(rule subtree_refute)
   337       proof(rule subtree_refute)
   220         show "Th th1 \<notin> ancestors (RAG s) (Th th)"
   338         show "Th th1 \<notin> ancestors (RAG s) (Th th)"
   221           by (unfold ancestors_th, simp)
   339             by (unfold ancestors_th, simp)
   222       next
   340       next
   223         from assms show "Th th1 \<noteq> Th th" by simp
   341         from assms show "Th th1 \<noteq> Th th" by simp
   224       qed
   342       qed
   225       moreover have "(Cs cs) \<notin>  subtree (RAG s) (Th th1)"
   343       moreover have "(Cs cs) \<notin>  subtree (RAG s) (Th th1)"
   226       proof(rule subtree_refute)
   344       proof(rule subtree_refute)
   229       qed simp
   347       qed simp
   230       ultimately have "{Th th, Cs cs} \<inter> subtree (RAG s) (Th th1) = {}" by auto
   348       ultimately have "{Th th, Cs cs} \<inter> subtree (RAG s) (Th th1) = {}" by auto
   231       thus ?thesis by simp
   349       thus ?thesis by simp
   232      qed
   350      qed
   233   qed
   351   qed
       
   352   -- {* The second step is to show the addition of edges does not change the sub-tree *}
   234   moreover have "subtree ?RAG'' (Th th1) =  subtree ?RAG' (Th th1)"
   353   moreover have "subtree ?RAG'' (Th th1) =  subtree ?RAG' (Th th1)"
   235   proof(rule subtree_insert_next)
   354   proof(rule subset_insert_subtree_outside)
   236     show "Th taker \<notin> subtree (RAG s - {(Cs cs, Th th), (Th taker, Cs cs)}) (Th th1)"
   355     show "Range {(Cs cs, Th taker)} \<inter> 
   237     proof(rule subtree_refute)
   356           subtree (RAG s - {(Cs cs, Th th), (Th taker, Cs cs)}) (Th th1) = {}"
   238       show "Th th1 \<notin> ancestors (RAG s - {(Cs cs, Th th), (Th taker, Cs cs)}) (Th taker)"
   357     proof -
       
   358      have "Th taker \<notin> subtree (RAG s - {(Cs cs, Th th), (Th taker, Cs cs)}) (Th th1)"
       
   359      proof(rule subtree_refute)
       
   360         show "Th th1 \<notin> ancestors (RAG s - {(Cs cs, Th th), (Th taker, Cs cs)}) (Th taker)"
   239             (is "_ \<notin> ?R")
   361             (is "_ \<notin> ?R")
   240       proof -
   362         proof -
   241           have "?R \<subseteq> ancestors (RAG s) (Th taker)" by (rule ancestors_mono, auto)
   363           have "?R \<subseteq> ancestors (RAG s) (Th taker)" by (rule ancestors_mono, auto)
   242           moreover have "Th th1 \<notin> ..." using ancestors_th' assms by simp
   364           moreover have "Th th1 \<notin> ..." using ancestors_th' assms by simp
   243           ultimately show ?thesis by auto
   365           ultimately show ?thesis by auto
   244       qed
   366         qed
   245     next
   367      next
   246       from assms show "Th th1 \<noteq> Th taker" by simp
   368         from assms show "Th th1 \<noteq> Th taker" by simp
       
   369      qed
       
   370      thus ?thesis by auto
   247     qed
   371     qed
   248   qed
   372   qed
   249   ultimately show ?thesis by (unfold RAG_s, simp)
   373   ultimately show ?thesis by (unfold RAG_s, simp)
   250 qed
   374 qed
   251 
   375 
       
   376 text {* 
       
   377   The following lemma shows threads not involved in the @{text V}-operation (i.e.
       
   378   threads other than @{text th} and @{text taker}) do not need to do any @{text cp}-recalculation.
       
   379   The reason is simple: according to @{thm subtree_kept}, the sub-trees of such threads 
       
   380   are not changed , additionally, since the @{text V}-operation does not change any precedence, 
       
   381   the @{text "cp"}-value of such threads are not changed.
       
   382 *}
   252 lemma cp_kept:
   383 lemma cp_kept:
   253   assumes "th1 \<notin> {th, taker}"
   384   assumes "th1 \<notin> {th, taker}"
   254   shows "cp (e#s) th1 = cp s th1"
   385   shows "cp (e#s) th1 = cp s th1"
   255     by (unfold cp_alt_def the_preced_es subtree_kept[OF assms], simp)
   386     by (unfold cp_alt_def the_preced_es subtree_kept[OF assms], simp)
   256 
   387 
       
   388 text {*
       
   389   Lemma @{thm cp_kept} also means @{text cp}-recalculation is needed only for
       
   390   @{text th} and @{text taker}. The following lemmas are to ensure that
       
   391   the recalculation can done locally using {\em local recalculation principle}.
       
   392   Since @{text taker} and @{text th} are the only threads with changed @{text cp}-values
       
   393   and neither one can not be a child of the other, it can be concluded that 
       
   394   neither of these two threads has children with changed @{text cp}-value.
       
   395   It means the recursive calls in @{thm cp_rec_tG} will not descend when recalculating 
       
   396   the @{text cp}-values for @{text th} and @{text taker}.
       
   397 *}
       
   398 
       
   399 lemma "taker \<notin> children (tG (e#s)) th"
       
   400   by (metis children_subtree empty_iff in_mono neq_taker_th root_def set_mp
       
   401           subtree_ancestorsI taker_ready_es vat_es.root_readys_tG)
       
   402   
       
   403 
       
   404 lemma "th \<notin> children (tG (e#s)) taker"
       
   405   by (metis children_subtree empty_iff  neq_taker_th root_def 
       
   406          subsetD subtree_ancestorsI th_ready_es vat_es.root_readys_tG)
       
   407   
       
   408 
   257 end
   409 end
   258 
   410 
   259 
   411 text {*
       
   412   The following locale @{text valid_trace_v_e} deals with the second sub-case 
       
   413   of @{text V}-operation, where there is no thread to take over the release 
       
   414   resource @{text cs}.
       
   415 *}
   260 context valid_trace_v_e
   416 context valid_trace_v_e
   261 begin
   417 begin
   262 
   418 
       
   419 text {*
       
   420   Since no thread to take over @{text cs}, only the edge representing 
       
   421   the holding of @{text cs} by @{text th} needs to be removed:
       
   422 *}
   263 lemma RAG_s: "RAG (e#s) = RAG s - {(Cs cs, Th th)}"
   423 lemma RAG_s: "RAG (e#s) = RAG s - {(Cs cs, Th th)}"
   264   by (unfold RAG_es waiting_set_eq holding_set_eq, simp)
   424   by (unfold RAG_es waiting_set_eq holding_set_eq, simp)
   265 
   425 
       
   426 text {*
       
   427   Since @{text th} has no ancestors, 
       
   428   the removal of the holding edge only affects the sub-tree of @{text th}:
       
   429 *}
   266 lemma subtree_kept:
   430 lemma subtree_kept:
   267   assumes "th1 \<noteq> th"
   431   assumes "th1 \<noteq> th"
   268   shows "subtree (RAG (e#s)) (Th th1) = subtree (RAG s) (Th th1)"
   432   shows "subtree (RAG (e#s)) (Th th1) = subtree (RAG s) (Th th1)"
   269 proof(unfold RAG_s, rule subset_del_subtree_outside)
   433 proof(unfold RAG_s, rule subset_del_subtree_outside)
   270   show "Range {(Cs cs, Th th)} \<inter> subtree (RAG s) (Th th1) = {}"
   434   show "Range {(Cs cs, Th th)} \<inter> subtree (RAG s) (Th th1) = {}"
   278     qed
   442     qed
   279     thus ?thesis by auto
   443     thus ?thesis by auto
   280   qed
   444   qed
   281 qed
   445 qed
   282 
   446 
       
   447 text {*
       
   448   From lemma @{thm subtree_kept} and the fact that no precedence are changed, it 
       
   449   can be derived the @{text cp}-values of all threads (except @{text th})
       
   450   are not changed and therefore need no recalculation:
       
   451 *}
   283 lemma cp_kept_1:
   452 lemma cp_kept_1:
   284   assumes "th1 \<noteq> th"
   453   assumes "th1 \<noteq> th"
   285   shows "cp (e#s) th1 = cp s th1"
   454   shows "cp (e#s) th1 = cp s th1"
   286     by (unfold cp_alt_def the_preced_es subtree_kept[OF assms], simp)
   455     by (unfold cp_alt_def the_preced_es subtree_kept[OF assms], simp)
       
   456 
       
   457 text {*
       
   458   The next several lemmas try to show that even the @{text cp}-value of 
       
   459   @{text th} needs not be recalculated.
       
   460  
       
   461   Although the @{text V}-operation detaches the sub-tree of @{text cs}
       
   462   from the sub-tree of @{text th}, the @{text cp}-value of @{text th} 
       
   463   is not affected. The reason is given by the following lemma @{text subtree_cs}, which
       
   464   says that the sub-tree of @{text cs} contains only itself. 
       
   465 
       
   466   According to @{text subtree_cs}, the detached sub-tree contains no thread node and
       
   467   therefore makes no contribution to the @{text cp}-value of @{text th}, 
       
   468   so its removal does not affect the @{text cp}-value neither, as confirmed 
       
   469   by the lemma @{text cp_kept_2}.
       
   470 *}
   287 
   471 
   288 lemma subtree_cs: "subtree (RAG s) (Cs cs) = {Cs cs}"
   472 lemma subtree_cs: "subtree (RAG s) (Cs cs) = {Cs cs}"
   289   (is "?L = ?R")
   473   (is "?L = ?R")
   290 proof -
   474 proof -
   291   { fix n
   475   { fix n
   306     assume "n \<in> ?R"
   490     assume "n \<in> ?R"
   307     hence "n \<in> ?L" by (auto simp:subtree_def)
   491     hence "n \<in> ?L" by (auto simp:subtree_def)
   308   } ultimately show ?thesis by auto
   492   } ultimately show ?thesis by auto
   309 qed
   493 qed
   310 
   494 
   311 
   495 text {*
       
   496   The following @{text "subtree_th"} is just a technical lemma.
       
   497 *}
   312 lemma subtree_th: 
   498 lemma subtree_th: 
   313   "subtree (RAG (e#s)) (Th th) = subtree (RAG s) (Th th) - {Cs cs}"
   499   "subtree (RAG (e#s)) (Th th) = subtree (RAG s) (Th th) - {Cs cs}"
   314 proof(unfold RAG_s, fold subtree_cs, rule forest_RAG.subtree_del_inside)
   500 proof(unfold RAG_s, fold subtree_cs, rule forest_RAG.subtree_del_inside)
   315   from edge_of_th
   501   from edge_of_th
   316   show "(Cs cs, Th th) \<in> edges_in (RAG s) (Th th)"
   502   show "(Cs cs, Th th) \<in> edges_in (RAG s) (Th th)"
   319 
   505 
   320 lemma cp_kept_2: 
   506 lemma cp_kept_2: 
   321   shows "cp (e#s) th = cp s th" 
   507   shows "cp (e#s) th = cp s th" 
   322  by (unfold cp_alt_def subtree_th the_preced_es, auto)
   508  by (unfold cp_alt_def subtree_th the_preced_es, auto)
   323 
   509 
       
   510 text {*
       
   511   By combining @{thm cp_kept_1} and @{thm cp_kept_2}, it is shown that no @{text cp}-recalculation 
       
   512   is needed at all for this sub-case of @{text V}-operation.
       
   513 *}
   324 lemma eq_cp:
   514 lemma eq_cp:
   325   shows "cp (e#s) th' = cp s th'"
   515   shows "cp (e#s) th' = cp s th'"
   326   using cp_kept_1 cp_kept_2
   516   using cp_kept_1 cp_kept_2
   327   by (cases "th' = th", auto)
   517   by (cases "th' = th", auto)
   328 
   518 
   329 end
   519 end
   330 
   520 
   331 
   521 section {* The @{term P} operation *} 
   332 section {* The @{term P} operation *}
   522 
       
   523 text {*
       
   524   Like @{text V}-operation, the treatment of @{text P}-operation is also divided into
       
   525   tow sub-cases. If the requested resource is available, it is dealt with in
       
   526   sub-locale @{text valid_trace_p_h}, otherwise, it is dealt with 
       
   527   in sub-locale @{text valid_trace_p_w}. 
       
   528 *}
       
   529 
       
   530 text {*
       
   531   But first, the following base locale @{text valid_trace_p} contains
       
   532   some general properties of the @{text P}-operation:
       
   533 *}
   333 
   534 
   334 context valid_trace_p
   535 context valid_trace_p
   335 begin
   536 begin
   336 
   537 
       
   538 text {*
       
   539   The following lemma shows that @{text th} is a root in the 
       
   540   @{text RAG} graph, which means @{text th} has no ancestors in the graph.
       
   541   The reason is that: since @{text th} is in running state, it is 
       
   542   in ready state, which means it is not waiting for any resource, therefore, 
       
   543   it has no outbound edge.  
       
   544 *}
   337 lemma root_th: "root (RAG s) (Th th)"
   545 lemma root_th: "root (RAG s) (Th th)"
   338   by (simp add: ready_th_s readys_root)
   546   by (simp add: ready_th_s readys_root)
   339 
   547 
       
   548 text {*
       
   549   For the same reason as @{thm root_th}, @{text th} is not in 
       
   550   the sub-tree of any thread other than @{text th}:
       
   551 *}
   340 lemma in_no_others_subtree:
   552 lemma in_no_others_subtree:
   341   assumes "th' \<noteq> th"
   553   assumes "th' \<noteq> th"
   342   shows "Th th \<notin> subtree (RAG s) (Th th')"
   554   shows "Th th \<notin> subtree (RAG s) (Th th')"
   343 proof
   555 proof
   344   assume "Th th \<in> subtree (RAG s) (Th th')"
   556   assume "Th th \<in> subtree (RAG s) (Th th')"
   350     case 2
   562     case 2
   351     with root_th show ?thesis by (auto simp:root_def)
   563     with root_th show ?thesis by (auto simp:root_def)
   352   qed
   564   qed
   353 qed
   565 qed
   354 
   566 
       
   567 text {*
       
   568   The following lemma confirms that the @{text P}-operation does not 
       
   569   affect the precedence of any thread. 
       
   570 *}
   355 lemma preced_kept: "the_preced (e#s) = the_preced s"
   571 lemma preced_kept: "the_preced (e#s) = the_preced s"
   356 proof
   572 proof
   357   fix th'
   573   fix th'
   358   show "the_preced (e # s) th' = the_preced s th'"
   574   show "the_preced (e # s) th' = the_preced s th'"
   359     by (unfold the_preced_def is_p preced_def, simp)
   575     by (unfold the_preced_def is_p preced_def, simp)
   360 qed
   576 qed
   361 
   577 
   362 end
   578 end
   363 
   579 
       
   580 text {*
       
   581   The following locale @{text valid_trace_p_h} deals with the 
       
   582   sub-case of @{text P}-operation when the requested @{text cs}
       
   583   is available and @{text th} gets hold of it instantaneously with 
       
   584   the @{text P}-operation.
       
   585 *}
   364 
   586 
   365 context valid_trace_p_h
   587 context valid_trace_p_h
   366 begin
   588 begin
       
   589 
       
   590 text {*
       
   591   According to @{thm RAG_es}, the only change to @{text RAG} by
       
   592   the @{text P}-operation is the addition of the edge @{text "(Cs cs, Th th)"}, 
       
   593   representing the newly acquisition of @{text cs} by @{text th}. 
       
   594   The following lemma shows that this newly added edge only change the sub-tree
       
   595   of @{text th}, the reason is that @{text th} is in no other sub-trees.
       
   596 *}
   367 
   597 
   368 lemma subtree_kept:
   598 lemma subtree_kept:
   369   assumes "th' \<noteq> th"
   599   assumes "th' \<noteq> th"
   370   shows "subtree (RAG (e#s)) (Th th') = subtree (RAG s) (Th th')"
   600   shows "subtree (RAG (e#s)) (Th th') = subtree (RAG s) (Th th')"
   371 proof(unfold RAG_es, rule subtree_insert_next)
   601 proof(unfold RAG_es, rule subtree_insert_next)
   372   from in_no_others_subtree[OF assms] 
   602   from in_no_others_subtree[OF assms] 
   373   show "Th th \<notin> subtree (RAG s) (Th th')" .
   603   show "Th th \<notin> subtree (RAG s) (Th th')" .
   374 qed
   604 qed
   375 
   605 
       
   606 text {*
       
   607   With both sub-tree and precdences unchanged, the @{text cp}-values of 
       
   608   threads other than @{text th} are not changed. Therefore, the 
       
   609   only recalculation of @{text cp}-value happens at @{text th}, and 
       
   610   the recalculation can be done locally using the 
       
   611   {\em local recalculation principle}, because the @{text cp}-values
       
   612   of its children are not changed.
       
   613 *}
   376 lemma cp_kept: 
   614 lemma cp_kept: 
   377   assumes "th' \<noteq> th"
   615   assumes "th' \<noteq> th"
   378   shows "cp (e#s) th' = cp s th'"
   616   shows "cp (e#s) th' = cp s th'"
   379 proof -
   617 proof -
   380   have "(the_preced (e#s) ` {th'a. Th th'a \<in> subtree (RAG (e#s)) (Th th')}) =
   618   have "(the_preced (e#s) ` {th'a. Th th'a \<in> subtree (RAG (e#s)) (Th th')}) =
   383   thus ?thesis by (unfold cp_alt_def, simp)
   621   thus ?thesis by (unfold cp_alt_def, simp)
   384 qed
   622 qed
   385 
   623 
   386 end
   624 end
   387 
   625 
       
   626 text {*
       
   627   The following locale @{text valid_trace_p_w} corresponds to 
       
   628   the case when the requested resource @{text cs} is not available and
       
   629   thread @{text th} is blocked.
       
   630 *}
       
   631 
   388 context valid_trace_p_w
   632 context valid_trace_p_w
   389 begin
   633 begin
   390 
   634 
   391 lemma cs_held: "(Cs cs, Th holder) \<in> RAG s"
   635 lemma cs_held: "(Cs cs, Th holder) \<in> RAG s"
   392   using holding_s_holder
   636   using holding_s_holder
   394 
   638 
   395 lemma tRAG_s: 
   639 lemma tRAG_s: 
   396   "tRAG (e#s) = tRAG s \<union> {(Th th, Th holder)}"
   640   "tRAG (e#s) = tRAG s \<union> {(Th th, Th holder)}"
   397   using RAG_tRAG_transfer[OF RAG_es cs_held] .
   641   using RAG_tRAG_transfer[OF RAG_es cs_held] .
   398 
   642 
       
   643 text {*
       
   644   The following lemma shows only the ancestors of @{text th} (the initiating 
       
   645   thread of the @{text P}-operation) may possibly 
       
   646   need a @{text cp}-recalculation. All other threads (including @{text th} itself)
       
   647   do not need @{text cp}-recalculation. 
       
   648 *}
   399 lemma cp_kept:
   649 lemma cp_kept:
   400   assumes "Th th'' \<notin> ancestors (tRAG (e#s)) (Th th)"
   650   assumes "Th th'' \<notin> ancestors (tRAG (e#s)) (Th th)"
   401   shows "cp (e#s) th'' = cp s th''"
   651   shows "cp (e#s) th'' = cp s th''"
   402 proof -
   652 proof -
   403   have h: "subtree (tRAG (e#s)) (Th th'') = subtree (tRAG s) (Th th'')"
   653   have h: "subtree (tRAG (e#s)) (Th th'') = subtree (tRAG s) (Th th'')"
   429     from this[folded tRAG_s] show ?thesis .
   679     from this[folded tRAG_s] show ?thesis .
   430   qed
   680   qed
   431   show ?thesis by (unfold cp_alt_def1 h preced_kept, simp)
   681   show ?thesis by (unfold cp_alt_def1 h preced_kept, simp)
   432 qed
   682 qed
   433 
   683 
       
   684 text {*
       
   685   Lemma @{thm cp_kept} means that the @{text cp}-recalculation starts from the parent of @{text th},
       
   686   going upwards along the chain of ancestors until one root (which is a thread 
       
   687   in ready queue) is reached. Actually, recalculation can terminate earlier, as 
       
   688   confirmed by the following two lemmas. 
       
   689 
       
   690   The first lemma @{text cp_gen_update_stop} is a technical lemma used to
       
   691   prove the lemma that follows.
       
   692 *}
   434 lemma cp_gen_update_stop: (* ddd *)
   693 lemma cp_gen_update_stop: (* ddd *)
   435   assumes "u \<in> ancestors (tRAG (e#s)) (Th th)"
   694   assumes "u \<in> ancestors (tRAG (e#s)) (Th th)"
   436   and "cp_gen (e#s) u = cp_gen s u"
   695   and "cp_gen (e#s) u = cp_gen s u"
   437   and "y \<in> ancestors (tRAG (e#s)) u"
   696   and "y \<in> ancestors (tRAG (e#s)) u"
   438   shows "cp_gen (e#s) y = cp_gen s y"
   697   shows "cp_gen (e#s) y = cp_gen s y"
   556       by (fold cp_gen_rec[OF eq_x], simp)
   815       by (fold cp_gen_rec[OF eq_x], simp)
   557     finally show ?thesis .
   816     finally show ?thesis .
   558   qed
   817   qed
   559 qed
   818 qed
   560 
   819 
       
   820 text {*
       
   821   The following lemma is about the possible early termination of 
       
   822   @{text cp}-recalculation. The lemma says that @{text cp}-recalculation 
       
   823   can terminate as soon as the recalculation yields an unchanged @{text cp}-value. 
       
   824 
       
   825   The @{text th'} in the lemma is assumed to be the first ancestor of @{text th}
       
   826   encountered by the recalculation procedure which has an unchanged @{text cp}-value 
       
   827   and the @{text th''} represents any thread upstream of @{text th'}. The lemma shows 
       
   828   that the @{text "cp"}-value @{text "th''"} is not changed, therefore, needs no 
       
   829   recalculation. It means the recalculation can be stop at @{text "th'"}.
       
   830 *}
   561 lemma cp_up:
   831 lemma cp_up:
   562   assumes "(Th th') \<in> ancestors (tRAG (e#s)) (Th th)"
   832   assumes "(Th th') \<in> ancestors (tRAG (e#s)) (Th th)"
   563   and "cp (e#s) th' = cp s th'"
   833   and "cp (e#s) th' = cp s th'"
   564   and "(Th th'') \<in> ancestors (tRAG (e#s)) (Th th')"
   834   and "(Th th'') \<in> ancestors (tRAG (e#s)) (Th th')"
   565   shows "cp (e#s) th'' = cp s th''"
   835   shows "cp (e#s) th'' = cp s th''"
   573   show ?thesis by metis
   843   show ?thesis by metis
   574 qed
   844 qed
   575 
   845 
   576 end
   846 end
   577 
   847 
       
   848 text {* 
       
   849   The following locale deals with the @{text Create}-operation.
       
   850 *}
       
   851 
   578 section {* The @{term Create} operation *}
   852 section {* The @{term Create} operation *}
   579 
   853 
   580 context valid_trace_create
   854 context valid_trace_create
   581 begin 
   855 begin 
   582 
   856 
       
   857 text {*
       
   858   Since @{text Create}-operation does not change @{text RAG} (according to 
       
   859   @{thm RAG_es}) and @{text tRAG} is determined uniquely by @{text RAG}, 
       
   860   therefore, @{text tRAG} is not not changed by @{text Create} neither.
       
   861 *}
   583 lemma tRAG_kept: "tRAG (e#s) = tRAG s"
   862 lemma tRAG_kept: "tRAG (e#s) = tRAG s"
   584   by (unfold tRAG_alt_def RAG_es, auto)
   863   by (unfold tRAG_alt_def RAG_es, auto)
   585 
   864 
       
   865 lemma tG_kept: "tG (e#s) = tG s"
       
   866   by (unfold tG_def tRAG_kept, simp)
       
   867 
       
   868 text {*
       
   869   The following lemma shows that @{text th} is completely isolated 
       
   870   from @{text RAG}.
       
   871 *}
       
   872 lemma th_not_in: "Th th \<notin> Field (tRAG s)"
       
   873   by (meson not_in_thread_isolated subsetCE tRAG_Field th_not_live_s)
       
   874 
       
   875 text {*
       
   876   Based on @{thm th_not_in}, it can be derived that @{text th} is also 
       
   877   isolated from @{text RAG}.
       
   878 *}
       
   879 lemma th_not_in_tG: "th \<notin> Field (tG s)"
       
   880   using tG_threads th_not_live_s by blast
       
   881   
       
   882 
       
   883 text {*
       
   884   The @{text Create}-operation does not change the precedences
       
   885   of other threads excepting sets a the initial precedence for the 
       
   886   thread being created (i.e. @{text th}).
       
   887 *}
   586 lemma preced_kept:
   888 lemma preced_kept:
   587   assumes "th' \<noteq> th"
   889   assumes "th' \<noteq> th"
   588   shows "the_preced (e#s) th' = the_preced s th'"
   890   shows "the_preced (e#s) th' = the_preced s th'"
   589   by (unfold the_preced_def preced_def is_create, insert assms, auto)
   891   by (unfold the_preced_def preced_def is_create, insert assms, auto)
   590 
   892 
   591 lemma th_not_in: "Th th \<notin> Field (tRAG s)"
   893 text {*
   592   by (meson not_in_thread_isolated subsetCE tRAG_Field th_not_live_s)
   894   The following lemma shows that the @{text cp}-values of
   593 
   895   all other threads need not be recalculated. The reason is twofold, first, 
       
   896   since @{text tG} is not changed, sub-trees of these threads are not changed;
       
   897   second, the precedences of the threads in these sub-trees are not changed (because 
       
   898   the only thread with a changed precedence is @{text th} and @{text th} is isolated
       
   899   from @{text tG}). 
       
   900 *}
   594 lemma eq_cp:
   901 lemma eq_cp:
   595   assumes neq_th: "th' \<noteq> th"
   902   assumes neq_th: "th' \<noteq> th"
   596   shows "cp (e#s) th' = cp s th'"
   903   shows "cp (e#s) th' = cp s th'"
   597 proof -
   904 proof -
   598   have "(the_preced (e#s) \<circ> the_thread) ` subtree (tRAG (e#s)) (Th th') =
   905   have "(the_preced (e # s) ` subtree (tG (e # s)) th') =
   599         (the_preced s \<circ> the_thread) ` subtree (tRAG s) (Th th')"
   906         (the_preced s ` subtree (tG s) th')"
   600   proof(unfold tRAG_kept, rule f_image_eq)
   907   proof -
   601     fix a
   908     { fix a
   602     assume a_in: "a \<in> subtree (tRAG s) (Th th')"
   909       assume "a \<in> subtree (tG s) th'"
   603     then obtain th_a where eq_a: "a = Th th_a" 
   910       with th_not_in_tG have "a \<noteq> th"
   604     proof(cases rule:subtreeE)
   911         by (metis ancestors_Field dm_tG_threads neq_th subtree_ancestorsI th_not_live_s) 
   605       case 2
   912       from preced_kept[OF this]  
   606       from ancestors_Field[OF 2(2)]
   913       have "the_preced (e # s) a = the_preced s a" .
   607       and that show ?thesis by (unfold tRAG_alt_def, auto)
   914     }
   608     qed auto
   915     thus ?thesis by (unfold tG_kept, auto intro!:f_image_eq)
   609     have neq_th_a: "th_a \<noteq> th"
   916   qed   
   610     proof -
   917   thus ?thesis by (unfold cp_alt_def2, simp)
   611       have "(Th th) \<notin> subtree (tRAG s) (Th th')"
   918 qed
   612       proof
   919 
   613         assume "Th th \<in> subtree (tRAG s) (Th th')"
   920 text {*
   614         thus False
   921   The following two lemmas deal with the @{text cp}-calculation of @{text th}. 
   615         proof(cases rule:subtreeE)
   922   The first lemma @{text children_of_th} says @{text th} has no children. 
   616           case 2
   923   The reason is simple, @{text th} is isolated from @{text "RAG"} before the
   617           from ancestors_Field[OF this(2)]
   924   @{term Create}-operation and @{text Create} does not change @{text RAG}, so 
   618           and th_not_in[unfolded Field_def]
   925   @{text th} keeps isolated after the operation.
   619           show ?thesis by auto
   926 *}
   620         qed (insert assms, auto)
       
   621       qed
       
   622       with a_in[unfolded eq_a] show ?thesis by auto
       
   623     qed
       
   624     from preced_kept[OF this]
       
   625     show "(the_preced (e#s) \<circ> the_thread) a = (the_preced s \<circ> the_thread) a"
       
   626       by (unfold eq_a, simp)
       
   627   qed
       
   628   thus ?thesis by (unfold cp_alt_def1, simp)
       
   629 qed
       
   630 
   927 
   631 lemma children_of_th: "RTree.children (tRAG (e#s)) (Th th) = {}"
   928 lemma children_of_th: "RTree.children (tRAG (e#s)) (Th th) = {}"
   632 proof -
   929 proof -
   633   { fix a
   930   { fix a
   634     assume "a \<in> RTree.children (tRAG (e#s)) (Th th)"
   931     assume "a \<in> RTree.children (tRAG (e#s)) (Th th)"
   636     with th_not_in have False 
   933     with th_not_in have False 
   637      by (unfold Field_def tRAG_kept, auto)
   934      by (unfold Field_def tRAG_kept, auto)
   638   } thus ?thesis by auto
   935   } thus ?thesis by auto
   639 qed
   936 qed
   640 
   937 
       
   938 text {*
       
   939   Now, since @{term th} has no children, by definition its @{text cp} value 
       
   940   equals its precedence:
       
   941 *}
   641 lemma eq_cp_th: "cp (e#s) th = preced th (e#s)"
   942 lemma eq_cp_th: "cp (e#s) th = preced th (e#s)"
   642  by (unfold vat_es.cp_rec children_of_th, simp add:the_preced_def)
   943  by (unfold vat_es.cp_rec children_of_th, simp add:the_preced_def)
   643 
   944 
   644 end
   945 end
   645 
   946 
   646 
   947 text {*
       
   948   The following locale @{text valid_trace_exit} deals with the @{term Exit}-operation.
       
   949 *}
   647 context valid_trace_exit
   950 context valid_trace_exit
   648 begin
   951 begin
       
   952 
       
   953 text {*
       
   954   The treatment of @{text Exit} is very similar to @{text Create}.
       
   955   First, the precedences of threads other than @{text th} are not changed.
       
   956 *}
   649 
   957 
   650 lemma preced_kept:
   958 lemma preced_kept:
   651   assumes "th' \<noteq> th"
   959   assumes "th' \<noteq> th"
   652   shows "the_preced (e#s) th' = the_preced s th'"
   960   shows "the_preced (e#s) th' = the_preced s th'"
   653   using assms
   961   using assms
   654   by (unfold the_preced_def is_exit preced_def, simp)
   962   by (unfold the_preced_def is_exit preced_def, simp)
   655 
   963 
       
   964 text {*
       
   965   Second, @{term tRAG} is not changed by @{text Exit} either.
       
   966 *}
   656 lemma tRAG_kept: "tRAG (e#s) = tRAG s"
   967 lemma tRAG_kept: "tRAG (e#s) = tRAG s"
   657   by (unfold tRAG_alt_def RAG_es, auto)
   968   by (unfold tRAG_alt_def RAG_es, auto)
       
   969 
       
   970 text {*
       
   971   Since @{term tG} is defined in terms of @{term tRAG}, @{term tG} is not changed neither.
       
   972 *}
       
   973 lemma tG_kept: "tG (e#s) = tG s"
       
   974   by (unfold tG_def tRAG_kept, simp)
   658 
   975 
   659 lemma th_RAG: "Th th \<notin> Field (RAG s)"
   976 lemma th_RAG: "Th th \<notin> Field (RAG s)"
   660 proof -
   977 proof -
   661   have "Th th \<notin> Range (RAG s)"
   978   have "Th th \<notin> Range (RAG s)"
   662   proof
   979   proof
   675     th_not_live_es valid_trace.dm_RAG_threads vat_es.valid_trace_axioms by blast
   992     th_not_live_es valid_trace.dm_RAG_threads vat_es.valid_trace_axioms by blast
   676   qed
   993   qed
   677   ultimately show ?thesis by (auto simp:Field_def)
   994   ultimately show ?thesis by (auto simp:Field_def)
   678 qed
   995 qed
   679 
   996 
       
   997 
   680 lemma th_tRAG: "(Th th) \<notin> Field (tRAG s)"
   998 lemma th_tRAG: "(Th th) \<notin> Field (tRAG s)"
   681   using th_RAG tRAG_Field by auto
   999   using th_RAG tRAG_Field by auto
   682 
  1000 
       
  1001 
       
  1002 text {*
       
  1003   Based on @{thm th_RAG}, it can be derived that @{text th} is also 
       
  1004   isolated from @{text tG}.
       
  1005 *}
       
  1006 lemma th_not_in_tG: "th \<notin> Field (tG s)"
       
  1007   using tG_kept vat_es.tG_threads by auto
       
  1008 
       
  1009 text {*
       
  1010   Because of @{thm preced_kept}, @{thm tG_kept} and @{thm th_tRAG},
       
  1011   the @{text cp}-values of all other threads are not changed. 
       
  1012   The reasoning is almost the same as that of @{term Create}:
       
  1013 *}
   683 lemma eq_cp:
  1014 lemma eq_cp:
   684   assumes neq_th: "th' \<noteq> th"
  1015   assumes neq_th: "th' \<noteq> th"
   685   shows "cp (e#s) th' = cp s th'"
  1016   shows "cp (e#s) th' = cp s th'"
   686 proof -
  1017 proof -
   687   have "(the_preced (e#s) \<circ> the_thread) ` subtree (tRAG (e#s)) (Th th') =
  1018   have "(the_preced (e # s) ` subtree (tG (e # s)) th') =
   688         (the_preced s \<circ> the_thread) ` subtree (tRAG s) (Th th')"
  1019         (the_preced s ` subtree (tG s) th')"
   689   proof(unfold tRAG_kept, rule f_image_eq)
  1020   proof -
   690     fix a
  1021     { fix a
   691     assume a_in: "a \<in> subtree (tRAG s) (Th th')"
  1022       assume "a \<in> subtree (tG s) th'"
   692     then obtain th_a where eq_a: "a = Th th_a" 
  1023       with th_not_in_tG have "a \<noteq> th"
   693     proof(cases rule:subtreeE)
  1024         by (metis ex_in_conv neq_th root_def root_readys_tG subtree_ancestorsI th_ready_s)
   694       case 2
  1025       from preced_kept[OF this]  
   695       from ancestors_Field[OF 2(2)]
  1026       have "the_preced (e # s) a = the_preced s a" .
   696       and that show ?thesis by (unfold tRAG_alt_def, auto)
  1027     }
   697     qed auto
  1028     thus ?thesis by (unfold tG_kept, auto intro!:f_image_eq)
   698     have neq_th_a: "th_a \<noteq> th"
  1029   qed   
   699     proof -
  1030   thus ?thesis by (unfold cp_alt_def2, simp)
   700       from readys_in_no_subtree[OF th_ready_s assms]
       
   701       have "(Th th) \<notin> subtree (RAG s) (Th th')" .
       
   702       with tRAG_subtree_RAG[of s "Th th'"]
       
   703       have "(Th th) \<notin> subtree (tRAG s) (Th th')" by auto
       
   704       with a_in[unfolded eq_a] show ?thesis by auto
       
   705     qed
       
   706     from preced_kept[OF this]
       
   707     show "(the_preced (e#s) \<circ> the_thread) a = (the_preced s \<circ> the_thread) a"
       
   708       by (unfold eq_a, simp)
       
   709   qed
       
   710   thus ?thesis by (unfold cp_alt_def1, simp)
       
   711 qed
  1031 qed
   712 
  1032 
   713 end
  1033 end
   714 
  1034 
   715 end
  1035 end