PrioGDef.thy
changeset 53 8142e80f5d58
parent 49 8679d75b1d76
equal deleted inserted replaced
49:8679d75b1d76 53:8142e80f5d58
       
     1 chapter {* Definitions *}
     1 (*<*)
     2 (*<*)
     2 theory PrioGDef
     3 theory PrioGDef
     3 imports Precedence_ord Moment
     4 imports Precedence_ord Moment
     4 begin
     5 begin
     5 (*>*)
     6 (*>*)
    68   -- {* Finished thread is removed: *}
    69   -- {* Finished thread is removed: *}
    69   "threads (Exit thread # s) = (threads s) - {thread}" | 
    70   "threads (Exit thread # s) = (threads s) - {thread}" | 
    70   -- {* Other kind of events does not affect the value of @{text "threads"}: *}
    71   -- {* Other kind of events does not affect the value of @{text "threads"}: *}
    71   "threads (e#s) = threads s" 
    72   "threads (e#s) = threads s" 
    72 
    73 
    73 text {* \noindent
    74 text {* 
    74   Functions such as @{text "threads"}, which extract information out of system states, are called
    75   \noindent
    75   {\em observing functions}. A series of observing functions will be defined in the sequel in order to 
    76   The function @{text "threads"} defined above is one of 
    76   model the protocol. 
    77   the so called {\em observation function}s which forms 
    77   Observing function @{text "priority"} calculates 
    78   the very basis of Paulson's inductive protocol verification method.
    78   the {\em original priority} of thread @{text "th"} in state @{text "s"}, expressed as
    79   Each observation function {\em observes} one particular aspect (or attribute)
    79   : @{text "priority th s" }. The {\em original priority} is the priority 
    80   of the system. For example, the attribute observed by  @{text "threads s"}
       
    81   is the set of threads living in state @{text "s"}. 
       
    82   The protocol being modelled 
       
    83   The decision made the protocol being modelled is based on the {\em observation}s
       
    84   returned by {\em observation function}s. Since {\observation function}s forms 
       
    85   the very basis on which Paulson's inductive method is based, there will be 
       
    86   a lot of such observation functions introduced in the following. In fact, any function 
       
    87   which takes event list as argument is a {\em observation function}.
       
    88   *}
       
    89 
       
    90 text {* \noindent
       
    91   Observation @{text "priority th s"} is
       
    92   the {\em original priority} of thread @{text "th"} in state @{text "s"}. 
       
    93   The {\em original priority} is the priority 
    80   assigned to a thread when it is created or when it is reset by system call 
    94   assigned to a thread when it is created or when it is reset by system call 
    81   @{text "Set thread priority"}.
    95   (represented by event @{text "Set thread priority"}).
    82 *}
    96 *}
    83 
    97 
    84 fun priority :: "thread \<Rightarrow> state \<Rightarrow> priority"
    98 fun priority :: "thread \<Rightarrow> state \<Rightarrow> priority"
    85   where
    99   where
    86   -- {* @{text "0"} is assigned to threads which have never been created: *}
   100   -- {* @{text "0"} is assigned to threads which have never been created: *}
    91      (if thread' = thread then prio else priority thread s)" |
   105      (if thread' = thread then prio else priority thread s)" |
    92   "priority thread (e#s) = priority thread s"
   106   "priority thread (e#s) = priority thread s"
    93 
   107 
    94 text {*
   108 text {*
    95   \noindent
   109   \noindent
    96   In the following,
   110   Observation @{text "last_set th s"} is the last time when the priority of thread @{text "th"} is set, 
    97   @{text "last_set th s"} is the last time when the priority of thread @{text "th"} is set, 
       
    98   observed from state @{text "s"}.
   111   observed from state @{text "s"}.
    99   The time in the system is measured by the number of events happened so far since the very beginning.
   112   The time in the system is measured by the number of events happened so far since the very beginning.
   100 *}
   113 *}
   101 fun last_set :: "thread \<Rightarrow> state \<Rightarrow> nat"
   114 fun last_set :: "thread \<Rightarrow> state \<Rightarrow> nat"
   102   where
   115   where
   175   \end{minipage}
   188   \end{minipage}
   176   *}
   189   *}
   177   cs_dependants_def: 
   190   cs_dependants_def: 
   178   "dependants (wq::cs \<Rightarrow> thread list) th \<equiv> {th' . (Th th', Th th) \<in> (RAG wq)^+}"
   191   "dependants (wq::cs \<Rightarrow> thread list) th \<equiv> {th' . (Th th', Th th) \<in> (RAG wq)^+}"
   179 
   192 
   180 text {*
       
   181   The data structure used by the operating system for scheduling is referred to as 
       
   182   {\em schedule state}. It is represented as a record consisting of 
       
   183   a function assigning waiting queue to resources 
       
   184   (to be used as the @{text "wq"} argument in @{text "holding"}, @{text "waiting"} 
       
   185   and  @{text "RAG"}, etc) and a function assigning precedence to threads:
       
   186   *}
       
   187 
       
   188 record schedule_state = 
       
   189     wq_fun :: "cs \<Rightarrow> thread list" -- {* The function assigning waiting queue. *}
       
   190     cprec_fun :: "thread \<Rightarrow> precedence" -- {* The function assigning precedence. *}
       
   191 
   193 
   192 text {* \noindent 
   194 text {* \noindent 
   193   The following
   195   The following
   194   @{text "cpreced s th"} gives the {\em current precedence} of thread @{text "th"} under
   196   @{text "cpreced s th"} gives the {\em current precedence} of thread @{text "th"} under
   195   state @{text "s"}. The definition of @{text "cpreced"} reflects the basic idea of 
   197   state @{text "s"}. The definition of @{text "cpreced"} reflects the basic idea of 
   201   *}
   203   *}
   202 
   204 
   203 definition cpreced :: "(cs \<Rightarrow> thread list) \<Rightarrow> state \<Rightarrow> thread \<Rightarrow> precedence"
   205 definition cpreced :: "(cs \<Rightarrow> thread list) \<Rightarrow> state \<Rightarrow> thread \<Rightarrow> precedence"
   204   where "cpreced wq s = (\<lambda>th. Max ((\<lambda>th'. preced th' s) ` ({th} \<union> dependants wq th)))"
   206   where "cpreced wq s = (\<lambda>th. Max ((\<lambda>th'. preced th' s) ` ({th} \<union> dependants wq th)))"
   205 
   207 
       
   208 text {*
       
   209   Notice that the current precedence (@{text "cpreced"}) of one thread @{text "th"} can be boosted 
       
   210   (becoming larger than its own precedence) by those threads in 
       
   211   the @{text "dependants wq th"}-set. If one thread get boosted, we say 
       
   212   it inherits the priority (or, more precisely, the precedence) of 
       
   213   its dependants. This is how the word "Inheritance" in 
       
   214   Priority Inheritance Protocol comes.
       
   215 *}
       
   216 
   206 (*<*)
   217 (*<*)
   207 lemma 
   218 lemma 
   208   cpreced_def2:
   219   cpreced_def2:
   209   "cpreced wq s th \<equiv> Max ({preced th s} \<union> {preced th' s | th'. th' \<in> dependants wq th})"
   220   "cpreced wq s th \<equiv> Max ({preced th s} \<union> {preced th' s | th'. th' \<in> dependants wq th})"
   210   unfolding cpreced_def image_def
   221   unfolding cpreced_def image_def
   211   apply(rule eq_reflection)
   222   apply(rule eq_reflection)
   212   apply(rule_tac f="Max" in arg_cong)
   223   apply(rule_tac f="Max" in arg_cong)
   213   by (auto)
   224   by (auto)
   214 (*>*)
   225 (*>*)
   215 
   226 
   216 (*
       
   217 abbreviation
       
   218   "all_unlocked \<equiv> \<lambda>_::cs. ([]::thread list)"
       
   219 
       
   220 abbreviation 
       
   221   "initial_cprec \<equiv> \<lambda>_::thread. Prc 0 0"
       
   222 *)
       
   223 
   227 
   224 text {* \noindent
   228 text {* \noindent
   225   Assuming @{text "qs"} be the waiting queue of a critical resource, 
   229   Assuming @{text "qs"} be the waiting queue of a critical resource, 
   226   the following abbreviation "release qs" is the waiting queue after the thread 
   230   the following abbreviation "release qs" is the waiting queue after the thread 
   227   holding the resource (which is thread at the head of @{text "qs"}) released
   231   holding the resource (which is thread at the head of @{text "qs"}) released
   240   from common sense that the thread who comes the earliest should take over.  
   244   from common sense that the thread who comes the earliest should take over.  
   241   The intention of this definition is to show that the choice of which thread to take over the 
   245   The intention of this definition is to show that the choice of which thread to take over the 
   242   release resource does not affect the correctness of the PIP protocol. 
   246   release resource does not affect the correctness of the PIP protocol. 
   243 *}
   247 *}
   244 
   248 
   245 (* ccc *)
   249 text {*
   246 
   250   The data structure used by the operating system for scheduling is referred to as 
   247 text {* \noindent
   251   {\em schedule state}. It is represented as a record consisting of 
   248   The following function @{text "schs"} is used to calculate the schedule state @{text "schs s"}
   252   a function assigning waiting queue to resources 
   249   out of the current system state @{text "s"}.
   253   (to be used as the @{text "wq"} argument in @{text "holding"}, @{text "waiting"} 
   250   It is the central function to model Priority Inheritance:
   254   and  @{text "RAG"}, etc) and a function assigning precedence to threads:
       
   255   *}
       
   256 
       
   257 record schedule_state = 
       
   258     wq_fun :: "cs \<Rightarrow> thread list" -- {* The function assigning waiting queue. *}
       
   259     cprec_fun :: "thread \<Rightarrow> precedence" -- {* The function assigning precedence. *}
       
   260 
       
   261 text {* \noindent
       
   262   The following two abbreviations (@{text "all_unlocked"} and @{text "initial_cprec"}) 
       
   263   are used to set the initial values of the @{text "wq_fun"} @{text "cprec_fun"} fields 
       
   264   respectively of the @{text "schedule_state"} record by the following function @{text "sch"},
       
   265   which is used to calculate the system's {\em schedule state}.
       
   266 
       
   267   Since there is no thread at the very beginning to make request, all critical resources 
       
   268   are free (or unlocked). This status is represented by the abbreviation
       
   269   @{text "all_unlocked"}. 
       
   270   *}
       
   271 abbreviation
       
   272   "all_unlocked \<equiv> \<lambda>_::cs. ([]::thread list)"
       
   273 
       
   274 
       
   275 text {* \noindent
       
   276   The initial current precedence for a thread can be anything, because there is no thread then. 
       
   277   We simply assume every thread has precedence @{text "Prc 0 0"}.
       
   278   *}
       
   279 
       
   280 abbreviation 
       
   281   "initial_cprec \<equiv> \<lambda>_::thread. Prc 0 0"
       
   282 
       
   283 
       
   284 text {* \noindent
       
   285   The following function @{text "schs"} is used to calculate the system's schedule state @{text "schs s"}
       
   286   out of the current system state @{text "s"}. It is the central function to model Priority Inheritance:
   251   *}
   287   *}
   252 fun schs :: "state \<Rightarrow> schedule_state"
   288 fun schs :: "state \<Rightarrow> schedule_state"
   253   where 
   289   where 
   254   "schs [] = (| wq_fun = \<lambda> cs. [],  cprec_fun = (\<lambda>_. Prc 0 0) |)" |
   290   -- {*
       
   291   \begin{minipage}{0.9\textwidth}
       
   292     Setting the initial value of the @{text "schedule_state"} record (see the explanations above).
       
   293   \end{minipage}
       
   294   *}
       
   295   "schs [] = (| wq_fun = all_unlocked,  cprec_fun = initial_cprec |)" |
   255 
   296 
   256   -- {*
   297   -- {*
   257   \begin{minipage}{0.9\textwidth}
   298   \begin{minipage}{0.9\textwidth}
   258   \begin{enumerate}
   299   \begin{enumerate}
   259   \item @{text "ps"} is the schedule state of last moment.
   300   \item @{text "ps"} is the schedule state of last moment.
   274   \end{enumerate}
   315   \end{enumerate}
   275   \item @{text "ncp"} is new precedence function, it is calculated from the newly updated waiting queue 
   316   \item @{text "ncp"} is new precedence function, it is calculated from the newly updated waiting queue 
   276         function. The RAGency of precedence function on waiting queue function is the reason to 
   317         function. The RAGency of precedence function on waiting queue function is the reason to 
   277         put them in the same record so that they can evolve together.
   318         put them in the same record so that they can evolve together.
   278   \end{enumerate}
   319   \end{enumerate}
       
   320   
       
   321 
       
   322   The calculation of @{text "cprec_fun"} depends on the value of @{text "wq_fun"}. 
       
   323   Therefore, in the following cases, @{text "wq_fun"} is always calculated first, in 
       
   324   the name of @{text "wq"} (if  @{text "wq_fun"} is not changed
       
   325   by the happening event) or @{text "new_wq"} (if the value of @{text "wq_fun"} is changed).
   279   \end{minipage}
   326   \end{minipage}
   280      *}
   327      *}
   281    "schs (Create th prio # s) = 
   328    "schs (Create th prio # s) = 
   282        (let wq = wq_fun (schs s) in
   329        (let wq = wq_fun (schs s) in
   283           (|wq_fun = wq, cprec_fun = cpreced wq (Create th prio # s)|))"
   330           (|wq_fun = wq, cprec_fun = cpreced wq (Create th prio # s)|))"
   285        (let wq = wq_fun (schs s) in
   332        (let wq = wq_fun (schs s) in
   286           (|wq_fun = wq, cprec_fun = cpreced wq (Exit th # s)|))"
   333           (|wq_fun = wq, cprec_fun = cpreced wq (Exit th # s)|))"
   287 |  "schs (Set th prio # s) = 
   334 |  "schs (Set th prio # s) = 
   288        (let wq = wq_fun (schs s) in
   335        (let wq = wq_fun (schs s) in
   289           (|wq_fun = wq, cprec_fun = cpreced wq (Set th prio # s)|))"
   336           (|wq_fun = wq, cprec_fun = cpreced wq (Set th prio # s)|))"
       
   337    -- {*
       
   338    \begin{minipage}{0.9\textwidth}
       
   339       Different from the forth coming cases, the @{text "wq_fun"} field of the schedule state 
       
   340       is changed. So, the new value is calculated first, in the name of @{text "new_wq"}.
       
   341    \end{minipage}   
       
   342    *}
   290 |  "schs (P th cs # s) = 
   343 |  "schs (P th cs # s) = 
   291        (let wq = wq_fun (schs s) in
   344        (let wq = wq_fun (schs s) in
   292         let new_wq = wq(cs := (wq cs @ [th])) in
   345         let new_wq = wq(cs := (wq cs @ [th])) in
   293           (|wq_fun = new_wq, cprec_fun = cpreced new_wq (P th cs # s)|))"
   346           (|wq_fun = new_wq, cprec_fun = cpreced new_wq (P th cs # s)|))"
   294 |  "schs (V th cs # s) = 
   347 |  "schs (V th cs # s) = 
   351   s_dependants_abv: 
   404   s_dependants_abv: 
   352   "dependants (s::state) \<equiv> dependants (wq_fun (schs s))"
   405   "dependants (s::state) \<equiv> dependants (wq_fun (schs s))"
   353 
   406 
   354 
   407 
   355 text {* 
   408 text {* 
   356   The following lemma can be proved easily:
   409   The following lemma can be proved easily, and the meaning is obvious.
   357   *}
   410   *}
   358 lemma
   411 lemma
   359   s_holding_def: 
   412   s_holding_def: 
   360   "holding (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th = hd (wq_fun (schs s) cs))"
   413   "holding (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th = hd (wq_fun (schs s) cs))"
   361   by (auto simp:s_holding_abv wq_def cs_holding_def)
   414   by (auto simp:s_holding_abv wq_def cs_holding_def)
   381 definition readys :: "state \<Rightarrow> thread set"
   434 definition readys :: "state \<Rightarrow> thread set"
   382   where "readys s \<equiv> {th . th \<in> threads s \<and> (\<forall> cs. \<not> waiting s th cs)}"
   435   where "readys s \<equiv> {th . th \<in> threads s \<and> (\<forall> cs. \<not> waiting s th cs)}"
   383 
   436 
   384 text {* \noindent
   437 text {* \noindent
   385   The following function @{text "runing"} calculates the set of running thread, which is the ready 
   438   The following function @{text "runing"} calculates the set of running thread, which is the ready 
   386   thread with the highest precedence. 
   439   thread with the highest precedence.  
   387   *}
   440   *}
   388 definition runing :: "state \<Rightarrow> thread set"
   441 definition runing :: "state \<Rightarrow> thread set"
   389   where "runing s \<equiv> {th . th \<in> readys s \<and> cp s th = Max ((cp s) ` (readys s))}"
   442   where "runing s \<equiv> {th . th \<in> readys s \<and> cp s th = Max ((cp s) ` (readys s))}"
       
   443 
       
   444 text {* \noindent
       
   445   Notice that the definition of @{text "running"} reflects the preemptive scheduling strategy,  
       
   446   because, if the @{text "running"}-thread (the one in @{text "runing"} set) 
       
   447   lowered its precedence by resetting its own priority to a lower
       
   448   one, it will lose its status of being the max in @{text "ready"}-set and be superseded.
       
   449 *}
   390 
   450 
   391 text {* \noindent
   451 text {* \noindent
   392   The following function @{text "holdents s th"} returns the set of resources held by thread 
   452   The following function @{text "holdents s th"} returns the set of resources held by thread 
   393   @{text "th"} in state @{text "s"}.
   453   @{text "th"} in state @{text "s"}.
   394   *}
   454   *}
   402 unfolding s_holding_abv
   462 unfolding s_holding_abv
   403 unfolding wq_def
   463 unfolding wq_def
   404 by (simp)
   464 by (simp)
   405 
   465 
   406 text {* \noindent
   466 text {* \noindent
   407   @{text "cntCS s th"} returns the number of resources held by thread @{text "th"} in
   467   Observation @{text "cntCS s th"} returns the number of resources held by thread @{text "th"} in
   408   state @{text "s"}:
   468   state @{text "s"}:
   409   *}
   469   *}
   410 definition cntCS :: "state \<Rightarrow> thread \<Rightarrow> nat"
   470 definition cntCS :: "state \<Rightarrow> thread \<Rightarrow> nat"
   411   where "cntCS s th = card (holdents s th)"
   471   where "cntCS s th = card (holdents s th)"
   412 
   472 
   413 text {* \noindent
   473 text {* \noindent
   414   The fact that event @{text "e"} is eligible to happen next in state @{text "s"} 
   474   According to the convention of Paulson's inductive method,
       
   475   the decision made by a protocol that event @{text "e"} is eligible to happen next under state @{text "s"} 
   415   is expressed as @{text "step s e"}. The predicate @{text "step"} is inductively defined as 
   476   is expressed as @{text "step s e"}. The predicate @{text "step"} is inductively defined as 
   416   follows:
   477   follows (notice how the decision is based on the {\em observation function}s 
       
   478   defined above, and also notice how a complicated protocol is modeled by a few simple 
       
   479   observations, and how such a kind of simplicity gives rise to improved trust on
       
   480   faithfulness):
   417   *}
   481   *}
   418 inductive step :: "state \<Rightarrow> event \<Rightarrow> bool"
   482 inductive step :: "state \<Rightarrow> event \<Rightarrow> bool"
   419   where
   483   where
   420   -- {* 
   484   -- {* 
   421   A thread can be created if it is not a live thread:
   485   A thread can be created if it is not a live thread:
   441   if it is running and holding that resource:
   505   if it is running and holding that resource:
   442   \end{minipage}
   506   \end{minipage}
   443   *}
   507   *}
   444   thread_V: "\<lbrakk>thread \<in> runing s;  holding s thread cs\<rbrakk> \<Longrightarrow> step s (V thread cs)" |
   508   thread_V: "\<lbrakk>thread \<in> runing s;  holding s thread cs\<rbrakk> \<Longrightarrow> step s (V thread cs)" |
   445   -- {*
   509   -- {*
   446   A thread can adjust its own priority as long as it is current running:
   510   \begin{minipage}{0.9\textwidth}
       
   511   A thread can adjust its own priority as long as it is current running. 
       
   512   With the resetting of one thread's priority, its precedence may change. 
       
   513   If this change lowered the precedence, according to the definition of @{text "running"}
       
   514   function, 
       
   515   \end{minipage}
   447   *}  
   516   *}  
   448   thread_set: "\<lbrakk>thread \<in> runing s\<rbrakk> \<Longrightarrow> step s (Set thread prio)"
   517   thread_set: "\<lbrakk>thread \<in> runing s\<rbrakk> \<Longrightarrow> step s (Set thread prio)"
   449 
   518 
   450 text {* \noindent
   519 text {*
   451   With predicate @{text "step"}, the fact that @{text "s"} is a legal state in 
   520   In Paulson's inductive method, every protocol is defined by such a @{text "step"}
   452   Priority Inheritance protocol can be expressed as: @{text "vt step s"}, where
   521   predicate. For instance, the predicate @{text "step"} given above 
       
   522   defines the PIP protocol. So, it can also be called "PIP".
       
   523 *}
       
   524 
       
   525 abbreviation
       
   526   "PIP \<equiv> step"
       
   527 
       
   528 
       
   529 text {* \noindent
       
   530   For any protocol defined by a @{text "step"} predicate, 
       
   531   the fact that @{text "s"} is a legal state in 
       
   532   the protocol is expressed as: @{text "vt step s"}, where
   453   the predicate @{text "vt"} can be defined as the following:
   533   the predicate @{text "vt"} can be defined as the following:
   454   *}
   534   *}
   455 inductive vt :: "state \<Rightarrow> bool"
   535 inductive vt :: "state \<Rightarrow> bool"
   456   where
   536   where
   457   -- {* Empty list @{text "[]"} is a legal state in any protocol:*}
   537   -- {* Empty list @{text "[]"} is a legal state in any protocol:*}
   458   vt_nil[intro]: "vt []" |
   538   vt_nil[intro]: "vt []" |
   459   -- {* 
   539   -- {* 
   460   \begin{minipage}{0.9\textwidth}
   540   \begin{minipage}{0.9\textwidth}
   461   If @{text "s"} a legal state, and event @{text "e"} is eligible to happen
   541   If @{text "s"} a legal state of the protocol defined by predicate @{text "step"}, 
   462   in state @{text "s"}, then @{text "e#s"} is a legal state as well:
   542   and event @{text "e"} is allowed to happen under state @{text "s"} by the protocol 
       
   543   predicate @{text "step"}, then @{text "e#s"} is a new legal state rendered by the 
       
   544   happening of @{text "e"}:
   463   \end{minipage}
   545   \end{minipage}
   464   *}
   546   *}
   465   vt_cons[intro]: "\<lbrakk>vt s; step s e\<rbrakk> \<Longrightarrow> vt (e#s)"
   547   vt_cons[intro]: "\<lbrakk>vt s; step s e\<rbrakk> \<Longrightarrow> vt (e#s)"
   466 
   548 
   467 text {*  \noindent
   549 text {*  \noindent
   468   It is easy to see that the definition of @{text "vt"} is generic. It can be applied to 
   550   It is easy to see that the definition of @{text "vt"} is generic. It can be applied to 
   469   any step predicate to get the set of legal states.
   551   any specific protocol specified by a @{text "step"}-predicate to get the set of
   470   *}
   552   legal states of that particular protocol.
   471 
   553   *}
   472 text {* \noindent
   554 
   473   The following two functions @{text "the_cs"} and @{text "the_th"} are used to extract
   555 text {* 
       
   556   The following are two very basic properties of @{text "vt"}.
       
   557 *}
       
   558 
       
   559 lemma step_back_vt: "vt (e#s) \<Longrightarrow> vt s"
       
   560   by(ind_cases "vt (e#s)", simp)
       
   561 
       
   562 lemma step_back_step: "vt (e#s) \<Longrightarrow> step s e"
       
   563   by(ind_cases "vt (e#s)", simp)
       
   564 
       
   565 text {* \noindent
       
   566   The following two auxiliary functions @{text "the_cs"} and @{text "the_th"} are used to extract
   474   critical resource and thread respectively out of RAG nodes.
   567   critical resource and thread respectively out of RAG nodes.
   475   *}
   568   *}
   476 fun the_cs :: "node \<Rightarrow> cs"
   569 fun the_cs :: "node \<Rightarrow> cs"
   477   where "the_cs (Cs cs) = cs"
   570   where "the_cs (Cs cs) = cs"
   478 
   571 
   481 
   574 
   482 text {* \noindent
   575 text {* \noindent
   483   The following predicate @{text "next_th"} describe the next thread to 
   576   The following predicate @{text "next_th"} describe the next thread to 
   484   take over when a critical resource is released. In @{text "next_th s th cs t"}, 
   577   take over when a critical resource is released. In @{text "next_th s th cs t"}, 
   485   @{text "th"} is the thread to release, @{text "t"} is the one to take over.
   578   @{text "th"} is the thread to release, @{text "t"} is the one to take over.
       
   579   Notice how this definition is backed up by the @{text "release"} function and its use 
       
   580   in the @{text "V"}-branch of @{text "schs"} function. This @{text "next_th"} function
       
   581   is not needed for the execution of PIP. It is introduced as an auxiliary function 
       
   582   to state lemmas. The correctness of this definition will be confirmed by 
       
   583   lemmas @{text "step_v_hold_inv"}, @{text " step_v_wait_inv"}, 
       
   584   @{text "step_v_get_hold"} and @{text "step_v_not_wait"}.
   486   *}
   585   *}
   487 definition next_th:: "state \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> thread \<Rightarrow> bool"
   586 definition next_th:: "state \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> thread \<Rightarrow> bool"
   488   where "next_th s th cs t = (\<exists> rest. wq s cs = th#rest \<and> rest \<noteq> [] \<and> 
   587   where "next_th s th cs t = (\<exists> rest. wq s cs = th#rest \<and> rest \<noteq> [] \<and> 
   489                                                 t = hd (SOME q. distinct q \<and> set q = set rest))"
   588                                      t = hd (SOME q. distinct q \<and> set q = set rest))"
   490 
   589 
   491 text {* \noindent
   590 text {* \noindent
   492   The function @{text "count Q l"} is used to count the occurrence of situation @{text "Q"}
   591   The aux function @{text "count Q l"} is used to count the occurrence of situation @{text "Q"}
   493   in list @{text "l"}:
   592   in list @{text "l"}:
   494   *}
   593   *}
   495 definition count :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> nat"
   594 definition count :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> nat"
   496   where "count Q l = length (filter Q l)"
   595   where "count Q l = length (filter Q l)"
   497 
   596 
   498 text {* \noindent
   597 text {* \noindent
   499   The following @{text "cntP s"} returns the number of operation @{text "P"} happened 
   598   The following observation @{text "cntP s"} returns the number of operation @{text "P"} happened 
   500   before reaching state @{text "s"}.
   599   before reaching state @{text "s"}.
   501   *}
   600   *}
   502 definition cntP :: "state \<Rightarrow> thread \<Rightarrow> nat"
   601 definition cntP :: "state \<Rightarrow> thread \<Rightarrow> nat"
   503   where "cntP s th = count (\<lambda> e. \<exists> cs. e = P th cs) s"
   602   where "cntP s th = count (\<lambda> e. \<exists> cs. e = P th cs) s"
   504 
   603 
   505 text {* \noindent
   604 text {* \noindent
   506   The following @{text "cntV s"} returns the number of operation @{text "V"} happened 
   605   The following observation @{text "cntV s"} returns the number of operation @{text "V"} happened 
   507   before reaching state @{text "s"}.
   606   before reaching state @{text "s"}.
   508   *}
   607   *}
   509 definition cntV :: "state \<Rightarrow> thread \<Rightarrow> nat"
   608 definition cntV :: "state \<Rightarrow> thread \<Rightarrow> nat"
   510   where "cntV s th = count (\<lambda> e. \<exists> cs. e = V th cs) s"
   609   where "cntV s th = count (\<lambda> e. \<exists> cs. e = V th cs) s"
   511 (*<*)
   610 (*<*)