59 fun isV :: "event \<Rightarrow> bool" where |
59 fun isV :: "event \<Rightarrow> bool" where |
60 "isV (V th cs) = True" | |
60 "isV (V th cs) = True" | |
61 "isV _ = False" |
61 "isV _ = False" |
62 |
62 |
63 text {* |
63 text {* |
64 As mentioned earlier, in Paulson's inductive method, the states of system are represented as lists |
64 |
65 of events, which is defined by the following type @{text "state"}: *} |
65 As mentioned earlier, in Paulson's inductive method, the states of system |
|
66 are represented as lists of events, which is defined by the following type |
|
67 @{text "state"}: *} |
66 |
68 |
67 type_synonym state = "event list" |
69 type_synonym state = "event list" |
68 |
70 |
69 |
71 |
70 text {* |
72 text {* |
71 Resource Allocation Graphs (RAG for short) are used extensively in our formal analysis. |
73 |
72 The following type @{text "node"} is used to represent the two types of nodes in RAGs. *} |
74 The function @{text "threads"} is used to calculate the set of live |
73 datatype node = |
75 threads (@{text "threads s"}) in state @{text "s"}. *} |
74 Th "thread" -- {* Node for a thread. *} |
|
75 | Cs "cs" -- {* Node for a critical resource. *} |
|
76 |
|
77 text {* |
|
78 The function @{text "threads"} is used to calculate the set of live threads (@{text "threads s"}) |
|
79 in state @{text "s"}. *} |
|
80 |
76 |
81 fun threads :: "state \<Rightarrow> thread set" |
77 fun threads :: "state \<Rightarrow> thread set" |
82 where |
78 where |
83 -- {* At the start of the system, the set of threads is empty: *} |
79 -- {* At the start of the system, the set of threads is empty: *} |
84 "threads [] = {}" | |
80 "threads [] = {}" | |
85 -- {* New thread is added to the @{text "threads"}: *} |
81 -- {* New thread is added to the @{text "threads"}: *} |
86 "threads (Create thread prio#s) = {thread} \<union> threads s" | |
82 "threads (Create th prio#s) = {th} \<union> threads s" | |
87 -- {* Finished thread is removed: *} |
83 -- {* Finished thread is removed: *} |
88 "threads (Exit thread # s) = (threads s) - {thread}" | |
84 "threads (Exit th # s) = (threads s) - {th}" | |
89 -- {* Other kind of events does not affect the value of @{text "threads"}: *} |
85 -- {* Other kind of events does not affect the value of @{text "threads"}: *} |
90 "threads (e#s) = threads s" |
86 "threads (e # s) = threads s" |
91 |
87 |
92 text {* |
88 text {* |
93 |
89 |
94 \noindent The function @{text "threads"} defined above is one of the |
90 \noindent The function @{text "threads"} is one of the {\em observation |
95 so called {\em observation function}s which forms the very basis of |
91 function}s which forms the very basis of Paulson's inductive protocol |
96 Paulson's inductive protocol verification method. Each observation |
92 verification method. Each observation function {\em observes} one |
97 function {\em observes} one particular aspect (or attribute) of the |
93 particular aspect (or attribute) of the system. For example, the attribute |
98 system. For example, the attribute observed by @{text "threads s"} |
94 observed by @{text "threads s"} is the set of threads living in state |
99 is the set of threads living in state @{text "s"}. The protocol |
95 @{text "s"}. The protocol being modelled The decision made the protocol |
100 being modelled The decision made the protocol being modelled is |
96 being modelled is based on the {\em observation}s returned by {\em |
101 based on the {\em observation}s returned by {\em observation |
97 observation function}s. Since {\observation function}s forms the very |
102 function}s. Since {\observation function}s forms the very basis on |
98 basis on which Paulson's inductive method is based, there will be a lot of |
103 which Paulson's inductive method is based, there will be a lot of |
|
104 such observation functions introduced in the following. In fact, any |
99 such observation functions introduced in the following. In fact, any |
105 function which takes event list as argument is a {\em observation |
100 function which takes event list as argument is a {\em observation |
106 function}. *} |
101 function}. *} |
107 |
102 |
108 text {* |
103 text {* |
109 |
104 |
110 \noindent Observation @{text "priority th s"} is the {\em original |
105 \noindent Observation @{text "priority th s"} is the {\em original |
111 priority} of thread @{text "th"} in state @{text "s"}. The {\em |
106 priority} of thread @{text "th"} in state @{text "s"}. The {\em original |
112 original priority} is the priority assigned to a thread when it is |
107 priority} is the priority assigned to a thread when it is created or when |
113 created or when it is reset by system call (represented by event |
108 it is reset by system call (represented by event @{text "Set thread |
114 @{text "Set thread priority"}). *} |
109 priority"}). *} |
115 |
110 |
116 fun priority :: "thread \<Rightarrow> state \<Rightarrow> priority" |
111 fun priority :: "thread \<Rightarrow> state \<Rightarrow> priority" |
117 where |
112 where |
118 -- {* @{text "0"} is assigned to threads which have never been created: *} |
113 -- {* @{text "0"} is assigned to threads which have never been created: *} |
119 "priority thread [] = 0" | |
114 "priority th [] = 0" | |
120 "priority thread (Create thread' prio#s) = |
115 "priority th (Create th' prio # s) = |
121 (if thread' = thread then prio else priority thread s)" | |
116 (if th' = th then prio else priority th s)" | |
122 "priority thread (Set thread' prio#s) = |
117 "priority th (Set th' prio # s) = |
123 (if thread' = thread then prio else priority thread s)" | |
118 (if th' = th then prio else priority th s)" | |
124 "priority thread (e#s) = priority thread s" |
119 "priority th (e # s) = priority th s" |
125 |
120 |
126 text {* |
121 text {* |
127 |
122 |
128 \noindent Observation @{text "last_set th s"} is the last time when |
123 \noindent Observation @{text "last_set th s"} is the last time when the |
129 the priority of thread @{text "th"} is set, observed from state |
124 priority of thread @{text "th"} is set, observed from state @{text "s"}. |
130 @{text "s"}. The time in the system is measured by the number of |
125 The time in the system is measured by the number of events happened so far |
131 events happened so far since the very beginning. *} |
126 since the very beginning. *} |
132 |
127 |
133 fun last_set :: "thread \<Rightarrow> state \<Rightarrow> nat" |
128 fun last_set :: "thread \<Rightarrow> state \<Rightarrow> nat" |
134 where |
129 where |
135 "last_set thread [] = 0" | |
130 "last_set th [] = 0" | |
136 "last_set thread ((Create thread' prio)#s) = |
131 "last_set th ((Create th' prio) # s) = |
137 (if (thread = thread') then length s else last_set thread s)" | |
132 (if (th = th') then length s else last_set th s)" | |
138 "last_set thread ((Set thread' prio)#s) = |
133 "last_set th ((Set th' prio) # s) = |
139 (if (thread = thread') then length s else last_set thread s)" | |
134 (if (th = th') then length s else last_set th s)" | |
140 "last_set thread (_#s) = last_set thread s" |
135 "last_set th (_ # s) = last_set th s" |
141 |
136 |
142 text {* |
137 text {* |
143 |
138 |
144 \noindent The {\em precedence} is a notion derived from {\em |
139 \noindent The {\em precedence} is a notion derived from {\em priority}, |
145 priority}, where the {\em precedence} of a thread is the combination |
140 where the {\em precedence} of a thread is the combination of its {\em |
146 of its {\em original priority} and {\em time} the priority is set. |
141 original priority} and the {\em time} the priority was set. The intention |
147 The intention is to discriminate threads with the same priority by |
142 is to discriminate threads with the same priority by giving threads whose |
148 giving threads whose priority is assigned earlier higher |
143 priority is assigned earlier higher precedences, because such threads are |
149 precedences, becasue such threads are more urgent to finish. This |
144 assumed more urgent to finish. *} |
150 explains the following definition: *} |
|
151 |
145 |
152 definition preced :: "thread \<Rightarrow> state \<Rightarrow> precedence" |
146 definition preced :: "thread \<Rightarrow> state \<Rightarrow> precedence" |
153 where "preced thread s \<equiv> Prc (priority thread s) (last_set thread s)" |
147 where "preced th s \<equiv> Prc (priority th s) (last_set th s)" |
154 |
148 |
155 |
149 definition preceds :: "thread set \<Rightarrow> state \<Rightarrow> precedence set" |
156 text {* |
150 where "preceds ths s \<equiv> {preced th s | th. th \<in> ths}" |
157 |
151 |
158 \noindent A number of important notions in PIP are represented as |
152 text {* |
159 the following functions, defined in terms of the waiting queues of |
153 |
160 the system, where the waiting queues , as a whole, is represented by |
154 \noindent A number of important notions in PIP are represented as the |
161 the @{text "wq"} argument of every notion function. The @{text |
155 following functions, defined in terms of the waiting queues of the system, |
162 "wq"} argument is itself a functions which maps every critical |
156 where the waiting queues, as a whole, is represented by the @{text "wq"} |
163 resource @{text "cs"} to the list of threads which are holding or |
157 argument of every notion function. The @{text "wq"} argument is itself a |
164 waiting for it. The thread at the head of this list is designated |
158 functions which maps every critical resource @{text "cs"} to the list of |
165 as the thread which is current holding the resrouce, which is |
159 threads which are holding or waiting for it. The thread at the head of |
166 slightly different from tradition where all threads in the waiting |
160 this list is designated as the thread which is current holding the |
167 queue are considered as waiting for the resource. *} |
161 resource, which is slightly different from tradition where all threads in |
168 |
162 the waiting queue are considered as waiting for the resource. *} |
169 (* |
163 |
170 consts |
164 text {* |
171 holding :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool" |
165 |
172 waiting :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool" |
166 \begin{minipage}{0.9\textwidth} This meaning of @{text "wq"} is reflected |
173 RAG :: "'b \<Rightarrow> (node \<times> node) set" |
167 in the following definition of @{text "holding wq th cs"}, where @{text |
174 dependants :: "'b \<Rightarrow> thread \<Rightarrow> thread set" |
168 "holding wq th cs"} means thread @{text "th"} is holding the critical |
175 *) |
169 resource @{text "cs"}. This decision is based on @{text "wq"}. |
176 |
170 \end{minipage} *} |
177 -- {* |
|
178 \begin{minipage}{0.9\textwidth} |
|
179 This meaning of @{text "wq"} is reflected in the following definition of |
|
180 @{text "holding wq th cs"}, where @{text "holding wq th cs"} means thread |
|
181 @{text "th"} is holding the critical resource @{text "cs"}. This decision |
|
182 is based on @{text "wq"}. |
|
183 \end{minipage} |
|
184 *} |
|
185 |
171 |
186 definition |
172 definition |
187 cs_holding_raw: |
|
188 "holding_raw wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread = hd (wq cs))" |
173 "holding_raw wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread = hd (wq cs))" |
189 |
174 |
|
175 text {* |
|
176 |
|
177 \begin{minipage}{0.9\textwidth} In accordance with the definition of |
|
178 @{text "holding wq th cs"}, a thread @{text "th"} is considered waiting |
|
179 for @{text "cs"} if it is in the {\em waiting queue} of critical resource |
|
180 @{text "cs"}, but not at the head. This is reflected in the definition of |
|
181 @{text "waiting wq th cs"} as follows: \end{minipage} *} |
190 |
182 |
191 definition |
183 definition |
192 -- {* |
|
193 \begin{minipage}{0.9\textwidth} |
|
194 In accordance with the definition of @{text "holding wq th cs"}, a thread |
|
195 @{text "th"} is considered waiting for @{text "cs"} if it is in the {\em |
|
196 waiting queue} of critical resource @{text "cs"}, but not at the head. |
|
197 This is reflected in the definition of @{text "waiting wq th cs"} as |
|
198 follows: |
|
199 \end{minipage} |
|
200 *} |
|
201 |
|
202 cs_waiting_raw: |
|
203 "waiting_raw wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread \<noteq> hd (wq cs))" |
184 "waiting_raw wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread \<noteq> hd (wq cs))" |
204 |
185 |
|
186 text {* |
|
187 |
|
188 Resource Allocation Graphs (RAG for short) are used extensively in our |
|
189 formal analysis. The following type @{text "node"} is used to represent |
|
190 the two types of nodes in RAGs. *} |
|
191 |
|
192 datatype node = |
|
193 Th "thread" -- {* Node for a thread. *} |
|
194 | Cs "cs" -- {* Node for a critical resource. *} |
|
195 |
|
196 |
|
197 text {* |
|
198 |
|
199 \begin{minipage}{0.9\textwidth} @{text "RAG wq"} generates RAG (a binary |
|
200 relations on @{text "node"}) out of waiting queues of the system |
|
201 (represented by the @{text "wq"} argument): \end{minipage} *} |
|
202 |
205 definition |
203 definition |
206 -- {* |
204 RAG_raw :: "(cs \<Rightarrow> thread list) => (node * node) set" |
207 \begin{minipage}{0.9\textwidth} |
205 where |
208 @{text "RAG wq"} generates RAG (a binary relations on @{text "node"}) out |
206 "RAG_raw wq \<equiv> |
209 of waiting queues of the system (represented by the @{text "wq"} |
207 {(Th th, Cs cs) | th cs. waiting_raw wq th cs} \<union> |
210 argument): \end{minipage} |
208 {(Cs cs, Th th) | cs th. holding_raw wq th cs}" |
211 *} |
209 |
212 |
210 text {* |
213 cs_RAG_raw: |
211 |
214 "RAG_raw (wq::cs \<Rightarrow> thread list) \<equiv> |
212 \begin{minipage}{0.9\textwidth} The following @{text "dependants wq th"} |
215 {(Th th, Cs cs) | th cs. waiting_raw wq th cs} \<union> {(Cs cs, Th th) | cs th. holding_raw wq th cs}" |
213 represents the set of threads which are RAGing on thread @{text "th"} in |
|
214 Resource Allocation Graph @{text "RAG wq"}. Here, "RAGing" means waiting |
|
215 directly or indirectly on the critical resource. \end{minipage} *} |
216 |
216 |
217 definition |
217 definition |
218 -- {* |
218 dependants_raw :: "(cs \<Rightarrow> thread list) \<Rightarrow> thread \<Rightarrow> thread set" |
219 \begin{minipage}{0.9\textwidth} |
219 where |
220 The following @{text "dependants wq th"} represents the set of threads |
220 "dependants_raw wq th \<equiv> {th' . (Th th', Th th) \<in> (RAG_raw wq)^+}" |
221 which are RAGing on thread @{text "th"} in Resource Allocation Graph |
221 |
222 @{text "RAG wq"}. Here, "RAGing" means waiting directly or indirectly on |
222 text {* |
223 the critical resource. |
223 |
224 \end{minipage} |
|
225 *} |
|
226 |
|
227 cs_dependants_def: |
|
228 "dependants_raw (wq::cs \<Rightarrow> thread list) th \<equiv> {th' . (Th th', Th th) \<in> (RAG_raw wq)^+}" |
|
229 |
|
230 text {* |
|
231 \noindent The following @{text "cpreced s th"} gives the {\em current |
224 \noindent The following @{text "cpreced s th"} gives the {\em current |
232 precedence} of thread @{text "th"} under state @{text "s"}. The definition |
225 precedence} of thread @{text "th"} under state @{text "s"}. The definition |
233 of @{text "cpreced"} reflects the basic idea of Priority Inheritance that |
226 of @{text "cpreced"} reflects the basic idea of Priority Inheritance that |
234 the {\em current precedence} of a thread is the precedence inherited from |
227 the {\em current precedence} of a thread is the precedence inherited from |
235 the maximum of all its dependants, i.e. the threads which are waiting |
228 the maximum of all its dependants, i.e. the threads which are waiting |
236 directly or indirectly waiting for some resources from it. If no such |
229 directly or indirectly waiting for some resources from it. If no such |
237 thread exits, @{text "th"}'s {\em current precedence} equals its original |
230 thread exits, @{text "th"}'s {\em current precedence} equals its original |
238 precedence, i.e. @{text "preced th s"}. |
231 precedence, i.e. @{text "preced th s"}. *} |
239 *} |
232 |
240 |
233 definition |
241 definition cpreced :: "(cs \<Rightarrow> thread list) \<Rightarrow> state \<Rightarrow> thread \<Rightarrow> precedence" |
234 cpreced :: "(cs \<Rightarrow> thread list) \<Rightarrow> state \<Rightarrow> thread \<Rightarrow> precedence" |
242 where "cpreced wq s = (\<lambda>th. Max ((\<lambda>th'. preced th' s) ` ({th} \<union> dependants_raw wq th)))" |
235 where |
243 |
236 "cpreced wq s th = Max ((\<lambda>th'. preced th' s) ` ({th} \<union> dependants_raw wq th))" |
244 text {* |
237 |
|
238 text {* |
|
239 |
245 Notice that the current precedence (@{text "cpreced"}) of one thread |
240 Notice that the current precedence (@{text "cpreced"}) of one thread |
246 @{text "th"} can be boosted (becoming larger than its own precedence) by |
241 @{text "th"} can be boosted (increased) by those threads in the @{text |
247 those threads in the @{text "dependants wq th"}-set. If one thread get |
242 "dependants wq th"}-set. If one thread gets boosted, we say it inherits |
248 boosted, we say it inherits the priority (or, more precisely, the |
243 the priority (or, more precisely, the precedence) of its dependants. This |
249 precedence) of its dependants. This is how the word "Inheritance" in |
244 is whrere the word "Inheritance" in Priority Inheritance Protocol comes |
250 Priority Inheritance Protocol comes. |
245 from. *} |
251 *} |
246 |
252 |
247 lemma cpreced_def2: |
253 (*<*) |
248 "cpreced wq s th \<equiv> Max ({preced th s} \<union> preceds (dependants_raw wq th) s)" |
254 lemma |
249 unfolding cpreced_def image_def preceds_def |
255 cpreced_def2: |
|
256 "cpreced wq s th \<equiv> Max ({preced th s} \<union> {preced th' s | th'. th' \<in> dependants_raw wq th})" |
|
257 unfolding cpreced_def image_def |
|
258 apply(rule eq_reflection) |
250 apply(rule eq_reflection) |
259 apply(rule_tac f="Max" in arg_cong) |
251 apply(rule_tac f="Max" in arg_cong) |
260 by (auto) |
252 by (auto) |
261 (*>*) |
|
262 |
|
263 |
253 |
264 text {* |
254 text {* |
265 |
255 |
266 \noindent Assuming @{text "qs"} be the waiting queue of a critical |
256 \noindent Assuming @{text "qs"} be the waiting queue of a critical |
267 resource, the following abbreviation "release qs" is the waiting queue |
257 resource, the following abbreviation "release qs" is the waiting queue |
268 after the thread holding the resource (which is thread at the head of |
258 after the thread holding the resource (which is thread at the head of |
269 @{text "qs"}) released the resource: |
259 @{text "qs"}) released the resource: *} |
270 *} |
|
271 |
260 |
272 abbreviation |
261 abbreviation |
273 "release qs \<equiv> case qs of |
262 "release qs \<equiv> case qs of |
274 [] => [] |
263 [] => [] |
275 | (_#qs') => (SOME q. distinct q \<and> set q = set qs')" |
264 | (_#qs') => (SOME q. distinct q \<and> set q = set qs')" |
276 |
265 |
277 text {* |
266 text {* |
|
267 |
278 \noindent It can be seen from the definition that the thread at the head |
268 \noindent It can be seen from the definition that the thread at the head |
279 of @{text "qs"} is removed from the return value, and the value @{term |
269 of @{text "qs"} is removed from the return value, and the value @{term |
280 "q"} is an reordering of @{text "qs'"}, the tail of @{text "qs"}. Through |
270 "q"} is an reordering of @{text "qs'"}, the tail of @{text "qs"}. Through |
281 this reordering, one of the waiting threads (those in @{text "qs'"} } is |
271 this reordering, one of the waiting threads (those in @{text "qs'"} } is |
282 chosen nondeterministically to be the head of the new queue @{text "q"}. |
272 chosen nondeterministically to be the head of the new queue @{text "q"}. |
283 Therefore, this thread is the one who takes over the resource. This is a |
273 Therefore, this thread is the one who takes over the resource. This is a |
284 little better different from common sense that the thread who comes the |
274 little better different from common sense that the thread who comes the |
285 earliest should take over. The intention of this definition is to show |
275 earliest should take over. The intention of this definition is to show |
286 that the choice of which thread to take over the release resource does not |
276 that the choice of which thread to take over the release resource does not |
287 affect the correctness of the PIP protocol. |
277 affect the correctness of the PIP protocol. *} |
288 *} |
278 |
289 |
279 text {* |
290 text {* |
280 |
291 The data structure used by the operating system for scheduling is referred |
281 The data structure used by the operating system for scheduling is referred |
292 to as {\em schedule state}. It is represented as a record consisting of a |
282 to as {\em schedule state}. It is represented as a record consisting of a |
293 function assigning waiting queue to resources (to be used as the @{text |
283 function assigning waiting queue to resources (to be used as the @{text |
294 "wq"} argument in @{text "holding"}, @{text "waiting"} and @{text "RAG"}, |
284 "wq"} argument in @{text "holding"}, @{text "waiting"} and @{text "RAG"}, |
295 etc) and a function assigning precedence to threads: |
285 etc) and a function assigning precedence to threads: *} |
296 *} |
|
297 |
286 |
298 record schedule_state = |
287 record schedule_state = |
299 wq_fun :: "cs \<Rightarrow> thread list" -- {* The function assigning waiting queue. *} |
288 wq_fun :: "cs \<Rightarrow> thread list" -- {* The function assigning waiting queue. *} |
300 cprec_fun :: "thread \<Rightarrow> precedence" -- {* The function assigning precedence. *} |
289 cprec_fun :: "thread \<Rightarrow> precedence" -- {* The function assigning precedence. *} |
301 |
290 |
302 text {* |
291 text {* |
|
292 |
303 \noindent The following two abbreviations (@{text "all_unlocked"} and |
293 \noindent The following two abbreviations (@{text "all_unlocked"} and |
304 @{text "initial_cprec"}) are used to set the initial values of the @{text |
294 @{text "initial_cprec"}) are used to set the initial values of the @{text |
305 "wq_fun"} @{text "cprec_fun"} fields respectively of the @{text |
295 "wq_fun"} @{text "cprec_fun"} fields respectively of the @{text |
306 "schedule_state"} record by the following function @{text "sch"}, which is |
296 "schedule_state"} record by the following function @{text "sch"}, which is |
307 used to calculate the system's {\em schedule state}. |
297 used to calculate the system's {\em schedule state}. |
453 |
432 |
454 definition |
433 definition |
455 s_dependants_abv: |
434 s_dependants_abv: |
456 "dependants (s::state) \<equiv> dependants_raw (wq_fun (schs s))" |
435 "dependants (s::state) \<equiv> dependants_raw (wq_fun (schs s))" |
457 |
436 |
458 |
437 text {* |
459 text {* |
438 |
460 The following lemma can be proved easily, and the meaning is obvious. |
439 The following four lemmas relate the @{term wq} and non-@{term wq} |
461 *} |
440 versions of @{term waiting}, @{term holding}, @{term dependants} and |
|
441 @{term cp}. *} |
|
442 |
|
443 lemma waiting_eq: |
|
444 shows "waiting s th cs = waiting_raw (wq s) th cs" |
|
445 by (simp add: s_waiting_abv wq_def) |
|
446 |
|
447 lemma holding_eq: |
|
448 shows "holding s th cs = holding_raw (wq s) th cs" |
|
449 by (simp add: s_holding_abv wq_def) |
|
450 |
|
451 lemma eq_dependants: |
|
452 shows "dependants_raw (wq s) = dependants s" |
|
453 by (simp add: s_dependants_abv wq_def) |
|
454 |
|
455 lemma cp_eq: |
|
456 shows "cp s th = cpreced (wq s) s th" |
|
457 unfolding cp_def wq_def |
|
458 apply(induct s rule: schs.induct) |
|
459 apply(simp add: Let_def cpreced_initial) |
|
460 apply(simp add: Let_def) |
|
461 apply(simp add: Let_def) |
|
462 apply(simp add: Let_def) |
|
463 apply(subst (2) schs.simps) |
|
464 apply(simp add: Let_def) |
|
465 apply(subst (2) schs.simps) |
|
466 apply(simp add: Let_def) |
|
467 done |
|
468 |
|
469 text {* |
|
470 |
|
471 The following lemma can be proved easily, and the meaning is obvious. *} |
462 |
472 |
463 lemma |
473 lemma |
464 s_holding_def: |
474 s_holding_def: |
465 "holding (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th = hd (wq_fun (schs s) cs))" |
475 "holding (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th = hd (wq_fun (schs s) cs))" |
466 by (auto simp:s_holding_abv wq_def cs_holding_raw) |
476 by (auto simp:s_holding_abv wq_def holding_raw_def) |
467 |
477 |
468 lemma s_waiting_def: |
478 lemma s_waiting_def: |
469 "waiting (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th \<noteq> hd (wq_fun (schs s) cs))" |
479 "waiting (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th \<noteq> hd (wq_fun (schs s) cs))" |
470 by (auto simp:s_waiting_abv wq_def cs_waiting_raw) |
480 by (auto simp:s_waiting_abv wq_def waiting_raw_def) |
471 |
481 |
472 lemma s_RAG_def: |
482 lemma s_RAG_def: |
473 "RAG (s::state) = |
483 "RAG (s::state) = |
474 {(Th th, Cs cs) | th cs. waiting_raw (wq s) th cs} \<union> {(Cs cs, Th th) | cs th. holding_raw (wq s) th cs}" |
484 {(Th th, Cs cs) | th cs. waiting_raw (wq s) th cs} \<union> |
475 by (auto simp:s_RAG_abv wq_def cs_RAG_raw) |
485 {(Cs cs, Th th) | cs th. holding_raw (wq s) th cs}" |
476 |
486 by (auto simp:s_RAG_abv wq_def RAG_raw_def) |
477 lemma |
487 |
478 s_dependants_def: |
488 lemma eq_RAG: |
479 "dependants (s::state) th \<equiv> {th' . (Th th', Th th) \<in> (RAG_raw (wq s))^+}" |
489 "RAG_raw (wq s) = RAG s" |
480 by (auto simp:s_dependants_abv wq_def cs_dependants_def) |
490 by (unfold RAG_raw_def s_RAG_def, auto) |
481 |
491 |
482 text {* |
492 |
|
493 lemma s_dependants_def: |
|
494 shows "dependants (s::state) th \<equiv> {th' . (Th th', Th th) \<in> (RAG s)^+}" |
|
495 using dependants_raw_def eq_RAG s_dependants_abv wq_def by auto |
|
496 |
|
497 text {* |
|
498 |
483 The following function @{text "readys"} calculates the set of ready |
499 The following function @{text "readys"} calculates the set of ready |
484 threads. A thread is {\em ready} for running if it is a live thread and it |
500 threads. A thread is {\em ready} for running if it is a live thread and it |
485 is not waiting for any critical resource. |
501 is not waiting for any critical resource. *} |
486 *} |
|
487 |
502 |
488 definition readys :: "state \<Rightarrow> thread set" |
503 definition readys :: "state \<Rightarrow> thread set" |
489 where "readys s \<equiv> {th . th \<in> threads s \<and> (\<forall> cs. \<not> waiting s th cs)}" |
504 where "readys s \<equiv> {th . th \<in> threads s \<and> (\<forall> cs. \<not> waiting s th cs)}" |
490 |
505 |
491 text {* |
506 text {* |
492 \noindent The following function @{text "runing"} calculates the set of |
507 |
493 running thread, which is the ready thread with the highest precedence. |
508 \noindent The following function @{text "running"} calculates the set of |
494 *} |
509 running thread, which is the ready thread with the highest precedence. *} |
495 |
510 |
496 definition runing :: "state \<Rightarrow> thread set" |
511 definition running :: "state \<Rightarrow> thread set" |
497 where "runing s \<equiv> {th . th \<in> readys s \<and> cp s th = Max ((cp s) ` (readys s))}" |
512 where "running s \<equiv> {th . th \<in> readys s \<and> cp s th = Max ((cp s) ` (readys s))}" |
498 |
513 |
499 text {* |
514 text {* |
|
515 |
500 \noindent Notice that the definition of @{text "running"} reflects the |
516 \noindent Notice that the definition of @{text "running"} reflects the |
501 preemptive scheduling strategy, because, if the @{text "running"}-thread |
517 preemptive scheduling strategy, because, if the @{text "running"}-thread |
502 (the one in @{text "runing"} set) lowered its precedence by resetting its |
518 (the one in @{text "running"} set) lowered its precedence by resetting its |
503 own priority to a lower one, it will lose its status of being the max in |
519 own priority to a lower one, it will lose its status of being the max in |
504 @{text "ready"}-set and be superseded. |
520 @{text "ready"}-set and be superseded. *} |
505 *} |
521 |
506 |
522 text {* |
507 text {* |
523 |
508 \noindent The following function @{text "holdents s th"} returns the set |
524 \noindent The following function @{text "holdents s th"} returns the set |
509 of resources held by thread @{text "th"} in state @{text "s"}. *} |
525 of resources held by thread @{text "th"} in state @{text "s"}. *} |
510 |
526 |
511 |
527 |
512 definition holdents :: "state \<Rightarrow> thread \<Rightarrow> cs set" |
528 definition holdents :: "state \<Rightarrow> thread \<Rightarrow> cs set" |
518 unfolding s_RAG_def |
534 unfolding s_RAG_def |
519 unfolding s_holding_abv |
535 unfolding s_holding_abv |
520 unfolding wq_def |
536 unfolding wq_def |
521 by (simp) |
537 by (simp) |
522 |
538 |
523 text {* \noindent |
539 text {* |
524 According to the convention of Paulson's inductive method, |
540 |
525 the decision made by a protocol that event @{text "e"} is eligible to happen next under state @{text "s"} |
541 \noindent According to the convention of Paulson's inductive method, the |
526 is expressed as @{text "step s e"}. The predicate @{text "step"} is inductively defined as |
542 decision made by a protocol that event @{text "e"} is eligible to happen |
527 follows (notice how the decision is based on the {\em observation function}s |
543 next under state @{text "s"} is expressed as @{text "step s e"}. The |
528 defined above, and also notice how a complicated protocol is modeled by a few simple |
544 predicate @{text "step"} is inductively defined as follows (notice how the |
529 observations, and how such a kind of simplicity gives rise to improved trust on |
545 decision is based on the {\em observation function}s defined above, and |
530 faithfulness): |
546 also notice how a complicated protocol is modeled by a few simple |
531 *} |
547 observations, and how such a kind of simplicity gives rise to improved |
|
548 trust on faithfulness): *} |
|
549 |
|
550 |
532 inductive step :: "state \<Rightarrow> event \<Rightarrow> bool" |
551 inductive step :: "state \<Rightarrow> event \<Rightarrow> bool" |
533 where |
552 where |
534 -- {* |
553 -- {* |
535 A thread can be created if it is not a live thread: |
554 A thread can be created if it is not a live thread: |
536 *} |
555 *} |
537 thread_create: "\<lbrakk>thread \<notin> threads s\<rbrakk> \<Longrightarrow> step s (Create thread prio)" | |
556 thread_create: "\<lbrakk>thread \<notin> threads s\<rbrakk> \<Longrightarrow> step s (Create thread prio)" | |
538 -- {* |
557 -- {* |
539 A thread can exit if it no longer hold any resource: |
558 A thread can exit if it no longer hold any resource: |
540 *} |
559 *} |
541 thread_exit: "\<lbrakk>thread \<in> runing s; holdents s thread = {}\<rbrakk> \<Longrightarrow> step s (Exit thread)" | |
560 thread_exit: "\<lbrakk>thread \<in> running s; holdents s thread = {}\<rbrakk> \<Longrightarrow> step s (Exit thread)" | |
542 -- {* |
561 -- {* |
543 \begin{minipage}{0.9\textwidth} |
562 \begin{minipage}{0.9\textwidth} |
544 A thread can request for an critical resource @{text "cs"}, if it is running and |
563 A thread can request for an critical resource @{text "cs"}, if it is running and |
545 the request does not form a loop in the current RAG. The latter condition |
564 the request does not form a loop in the current RAG. The latter condition |
546 is set up to avoid deadlock. The condition also reflects our assumption all threads are |
565 is set up to avoid deadlock. The condition also reflects our assumption all threads are |
547 carefully programmed so that deadlock can not happen: |
566 carefully programmed so that deadlock can not happen: |
548 \end{minipage} |
567 \end{minipage} |
549 *} |
568 *} |
550 thread_P: "\<lbrakk>thread \<in> runing s; (Cs cs, Th thread) \<notin> (RAG s)^+\<rbrakk> \<Longrightarrow> |
569 thread_P: "\<lbrakk>thread \<in> running s; (Cs cs, Th thread) \<notin> (RAG s)^+\<rbrakk> \<Longrightarrow> |
551 step s (P thread cs)" | |
570 step s (P thread cs)" | |
552 -- {* |
571 -- {* |
553 \begin{minipage}{0.9\textwidth} |
572 \begin{minipage}{0.9\textwidth} |
554 A thread can release a critical resource @{text "cs"} |
573 A thread can release a critical resource @{text "cs"} |
555 if it is running and holding that resource: |
574 if it is running and holding that resource: |
556 \end{minipage} |
575 \end{minipage} |
557 *} |
576 *} |
558 thread_V: "\<lbrakk>thread \<in> runing s; holding s thread cs\<rbrakk> \<Longrightarrow> step s (V thread cs)" | |
577 thread_V: "\<lbrakk>thread \<in> running s; holding s thread cs\<rbrakk> \<Longrightarrow> step s (V thread cs)" | |
559 -- {* |
578 -- {* |
560 \begin{minipage}{0.9\textwidth} |
579 \begin{minipage}{0.9\textwidth} |
561 A thread can adjust its own priority as long as it is current running. |
580 A thread can adjust its own priority as long as it is current running. |
562 With the resetting of one thread's priority, its precedence may change. |
581 With the resetting of one thread's priority, its precedence may change. |
563 If this change lowered the precedence, according to the definition of @{text "running"} |
582 If this change lowered the precedence, according to the definition of @{text "running"} |
564 function, |
583 function, |
565 \end{minipage} |
584 \end{minipage} |
566 *} |
585 *} |
567 thread_set: "\<lbrakk>thread \<in> runing s\<rbrakk> \<Longrightarrow> step s (Set thread prio)" |
586 thread_set: "\<lbrakk>thread \<in> running s\<rbrakk> \<Longrightarrow> step s (Set thread prio)" |
568 |
587 |
569 text {* |
588 text {* |
570 In Paulson's inductive method, every protocol is defined by such a @{text "step"} |
589 |
571 predicate. For instance, the predicate @{text "step"} given above |
590 In Paulson's inductive method, every protocol is defined by such a @{text |
572 defines the PIP protocol. So, it can also be called "PIP". |
591 "step"} predicate. For instance, the predicate @{text "step"} given above |
573 *} |
592 defines the PIP protocol. So, it can also be called "PIP". *} |
574 |
593 |
575 abbreviation |
594 abbreviation |
576 "PIP \<equiv> step" |
595 "PIP \<equiv> step" |
577 |
596 |
578 |
597 |
579 text {* \noindent |
598 text {* |
580 For any protocol defined by a @{text "step"} predicate, |
599 |
581 the fact that @{text "s"} is a legal state in |
600 \noindent For any protocol defined by a @{text "step"} predicate, the fact |
582 the protocol is expressed as: @{text "vt step s"}, where |
601 that @{text "s"} is a legal state in the protocol is expressed as: @{text |
583 the predicate @{text "vt"} can be defined as the following: |
602 "vt step s"}, where the predicate @{text "vt"} can be defined as the |
584 *} |
603 following: *} |
|
604 |
|
605 |
585 inductive vt :: "state \<Rightarrow> bool" |
606 inductive vt :: "state \<Rightarrow> bool" |
586 where |
607 where |
587 -- {* Empty list @{text "[]"} is a legal state in any protocol:*} |
608 -- {* Empty list @{text "[]"} is a legal state in any protocol:*} |
588 vt_nil[intro]: "vt []" | |
609 vt_nil[intro]: "vt []" | |
589 -- {* |
610 -- {* |