77 by (unfold vat_s.cp_rec, rule Max_ge, |
78 by (unfold vat_s.cp_rec, rule Max_ge, |
78 auto simp:the_preced_def vat_s.fsbttRAGs.finite_children) |
79 auto simp:the_preced_def vat_s.fsbttRAGs.finite_children) |
79 ultimately show ?thesis by auto |
80 ultimately show ?thesis by auto |
80 qed |
81 qed |
81 |
82 |
82 lemma highest_cp_preced: "cp s th = Max ((\<lambda> th'. preced th' s) ` threads s)" |
83 lemma highest_cp_preced: "cp s th = Max (the_preced s ` threads s)" |
83 by (fold max_cp_eq, unfold eq_cp_s_th, insert highest, simp) |
84 using eq_cp_s_th highest max_cp_eq the_preced_def by presburger |
84 |
85 |
85 lemma highest_preced_thread: "preced th s = Max ((\<lambda> th'. preced th' s) ` threads s)" |
86 |
|
87 lemma highest_preced_thread: "preced th s = Max (the_preced s ` threads s)" |
86 by (fold eq_cp_s_th, unfold highest_cp_preced, simp) |
88 by (fold eq_cp_s_th, unfold highest_cp_preced, simp) |
87 |
89 |
88 lemma highest': "cp s th = Max (cp s ` threads s)" |
90 lemma highest': "cp s th = Max (cp s ` threads s)" |
89 proof - |
91 by (simp add: eq_cp_s_th highest) |
90 from highest_cp_preced max_cp_eq[symmetric] |
|
91 show ?thesis by simp |
|
92 qed |
|
93 |
92 |
94 end |
93 end |
95 |
94 |
96 locale extend_highest_gen = highest_gen + |
95 locale extend_highest_gen = highest_gen + |
97 fixes t |
96 fixes t |
246 The proof goes by induction over @{text "t"} using the specialized |
244 The proof goes by induction over @{text "t"} using the specialized |
247 induction rule @{thm ind}, followed by case analysis of each possible |
245 induction rule @{thm ind}, followed by case analysis of each possible |
248 operations of PIP. All cases follow the same pattern rendered by the |
246 operations of PIP. All cases follow the same pattern rendered by the |
249 generalized introduction rule @{thm "image_Max_eqI"}. |
247 generalized introduction rule @{thm "image_Max_eqI"}. |
250 |
248 |
251 The very essence is to show that precedences, no matter whether they are newly introduced |
249 The very essence is to show that precedences, no matter whether they |
252 or modified, are always lower than the one held by @{term "th"}, |
250 are newly introduced or modified, are always lower than the one held |
253 which by @{thm th_kept} is preserved along the way. |
251 by @{term "th"}, which by @{thm th_kept} is preserved along the way. |
254 *} |
252 *} |
255 lemma max_kept: "Max (the_preced (t @ s) ` (threads (t@s))) = preced th s" |
253 lemma max_kept: "Max (the_preced (t @ s) ` (threads (t@s))) = preced th s" |
256 proof(induct rule:ind) |
254 proof(induct rule:ind) |
257 case Nil |
255 case Nil |
258 from highest_preced_thread |
256 from highest_preced_thread |
259 show ?case |
257 show ?case by simp |
260 by (unfold the_preced_def, simp) |
|
261 next |
258 next |
262 case (Cons e t) |
259 case (Cons e t) |
263 interpret h_e: extend_highest_gen _ _ _ _ "(e # t)" using Cons by auto |
260 interpret h_e: extend_highest_gen _ _ _ _ "(e # t)" using Cons by auto |
264 interpret h_t: extend_highest_gen _ _ _ _ t using Cons by auto |
261 interpret h_t: extend_highest_gen _ _ _ _ t using Cons by auto |
265 show ?case |
262 show ?case |
283 thus "?f x \<le> ?f th" |
280 thus "?f x \<le> ?f th" |
284 proof |
281 proof |
285 assume "x = thread" |
282 assume "x = thread" |
286 thus ?thesis |
283 thus ?thesis |
287 apply (simp add:Create the_preced_def preced_def, fold preced_def) |
284 apply (simp add:Create the_preced_def preced_def, fold preced_def) |
288 using Create h_e.create_low h_t.th_kept lt_tm preced_leI2 preced_th by force |
285 using Create h_e.create_low h_t.th_kept lt_tm preced_leI2 |
|
286 preced_th by force |
289 next |
287 next |
290 assume h: "x \<in> threads (t @ s)" |
288 assume h: "x \<in> threads (t @ s)" |
291 from Cons(2)[unfolded Create] |
289 from Cons(2)[unfolded Create] |
292 have "x \<noteq> thread" using h by (cases, auto) |
290 have "x \<noteq> thread" using h by (cases, auto) |
293 hence "?f x = the_preced (t@s) x" |
291 hence "?f x = the_preced (t@s) x" |
438 qed |
436 qed |
439 also have "... = ?R" by (simp add: max_preced the_preced_def) |
437 also have "... = ?R" by (simp add: max_preced the_preced_def) |
440 finally show ?thesis . |
438 finally show ?thesis . |
441 qed |
439 qed |
442 |
440 |
443 lemma th_cp_max: "cp (t@s) th = Max (cp (t@s) ` threads (t@s))" |
441 lemma th_cp_max[simp]: "Max (cp (t@s) ` threads (t@s)) = cp (t@s) th" |
444 using max_cp_eq th_cp_max_preced the_preced_def vt_t by presburger |
442 using max_cp_eq th_cp_max_preced the_preced_def vt_t by presburger |
445 |
443 |
446 lemma th_cp_preced: "cp (t@s) th = preced th s" |
444 lemma [simp]: "Max (cp (t@s) ` threads (t@s)) = Max (the_preced (t@s) ` threads (t@s))" |
|
445 by (simp add: th_cp_max_preced) |
|
446 |
|
447 lemma [simp]: "Max (the_preced (t@s) ` threads (t@s)) = the_preced (t@s) th" |
|
448 using max_kept th_kept the_preced_def by auto |
|
449 |
|
450 lemma [simp]: "the_preced (t@s) th = preced th (t@s)" |
|
451 using the_preced_def by auto |
|
452 |
|
453 lemma [simp]: "preced th (t@s) = preced th s" |
|
454 by (simp add: th_kept) |
|
455 |
|
456 lemma [simp]: "cp s th = preced th s" |
|
457 by (simp add: eq_cp_s_th) |
|
458 |
|
459 lemma th_cp_preced [simp]: "cp (t@s) th = preced th s" |
447 by (fold max_kept, unfold th_cp_max_preced, simp) |
460 by (fold max_kept, unfold th_cp_max_preced, simp) |
448 |
461 |
449 lemma preced_less: |
462 lemma preced_less: |
450 assumes th'_in: "th' \<in> threads s" |
463 assumes th'_in: "th' \<in> threads s" |
451 and neq_th': "th' \<noteq> th" |
464 and neq_th': "th' \<noteq> th" |
453 using assms |
466 using assms |
454 by (metis Max.coboundedI finite_imageI highest not_le order.trans |
467 by (metis Max.coboundedI finite_imageI highest not_le order.trans |
455 preced_linorder rev_image_eqI threads_s vat_s.finite_threads |
468 preced_linorder rev_image_eqI threads_s vat_s.finite_threads |
456 vat_s.le_cp) |
469 vat_s.le_cp) |
457 |
470 |
|
471 section {* The `blocking thread` *} |
|
472 |
|
473 text {* |
|
474 The purpose of PIP is to ensure that the most |
|
475 urgent thread @{term th} is not blocked unreasonably. |
|
476 Therefore, a clear picture of the blocking thread is essential |
|
477 to assure people that the purpose is fulfilled. |
|
478 |
|
479 In this section, we are going to derive a series of lemmas |
|
480 with finally give rise to a picture of the blocking thread. |
|
481 |
|
482 By `blocking thread`, we mean a thread in running state but |
|
483 different from thread @{term th}. |
|
484 *} |
|
485 |
458 text {* |
486 text {* |
459 The following lemmas shows that the @{term cp}-value |
487 The following lemmas shows that the @{term cp}-value |
460 of the blocking thread @{text th'} equals to the highest |
488 of the blocking thread @{text th'} equals to the highest |
461 precedence in the whole system. |
489 precedence in the whole system. |
462 *} |
490 *} |
469 also have "\<dots> = ?R" |
497 also have "\<dots> = ?R" |
470 by (metis th_cp_max th_cp_preced vat_t.max_cp_readys_threads) |
498 by (metis th_cp_max th_cp_preced vat_t.max_cp_readys_threads) |
471 finally show ?thesis . |
499 finally show ?thesis . |
472 qed |
500 qed |
473 |
501 |
474 section {* The `blocking thread` *} |
502 text {* |
475 |
503 The following lemma shows how the counting of |
476 text {* |
504 @{term "P"} and @{term "V"} operations affects |
477 Counting of the number of @{term "P"} and @{term "V"} operations |
505 the running state of threads in @{term t}. |
478 is the cornerstone of a large number of the following proofs. |
506 |
479 The reason is that this counting is quite easy to calculate and |
507 The lemma shows that if a thread's @{term "P"}-count equals |
480 convenient to use in the reasoning. |
508 its @{term "V"}-count (which means it no longer has any |
481 |
509 resource in its possession), it can not be in running thread. |
482 The following lemma shows that the counting controls whether |
510 |
483 a thread is running or not. |
511 The proof is by contraction with the assumption @{text "th' \<noteq> th"}. |
484 *} (* ccc *) |
512 The key is the use of @{thm count_eq_dependants} |
|
513 to derive the emptiness of @{text th'}s @{term dependants}-set |
|
514 from the balance of its @{term P} @{term V} counts. |
|
515 From this, it can be shown @{text th'}s @{term cp}-value |
|
516 equals to its own precedence. |
|
517 |
|
518 On the other hand, since @{text th'} is running, by |
|
519 @{thm runing_preced_inversion}, its @{term cp}-value |
|
520 equals to the precedence of @{term th}. |
|
521 |
|
522 Combining the above two we have that @{text th'} and |
|
523 @{term th} have the same precedence. By uniqueness of precedence, we |
|
524 have @{text "th' = th"}, which is in contradiction with the |
|
525 assumption @{text "th' \<noteq> th"}. |
|
526 *} |
485 |
527 |
486 lemma eq_pv_blocked: (* ddd *) |
528 lemma eq_pv_blocked: (* ddd *) |
487 assumes neq_th': "th' \<noteq> th" |
529 assumes neq_th': "th' \<noteq> th" |
488 and eq_pv: "cntP (t@s) th' = cntV (t@s) th'" |
530 and eq_pv: "cntP (t@s) th' = cntV (t@s) th'" |
489 shows "th' \<notin> runing (t@s)" |
531 shows "th' \<notin> runing (t@s)" |
505 -- {* Since the counts of @{term th'} are balanced, the subtree |
547 -- {* Since the counts of @{term th'} are balanced, the subtree |
506 of it contains only itself, so, its @{term cp}-value |
548 of it contains only itself, so, its @{term cp}-value |
507 equals its @{term preced}-value: *} |
549 equals its @{term preced}-value: *} |
508 have "?L = cp (t@s) th'" |
550 have "?L = cp (t@s) th'" |
509 by (unfold cp_eq_cpreced cpreced_def count_eq_dependants[OF eq_pv], simp) |
551 by (unfold cp_eq_cpreced cpreced_def count_eq_dependants[OF eq_pv], simp) |
510 -- {* Since @{term "th'"} is running by @{thm otherwise}, |
552 -- {* Since @{term "th'"} is running, by @{thm runing_preced_inversion}, |
511 it has the highest @{term cp}-value, by definition, |
553 its @{term cp}-value equals @{term "preced th s"}, |
512 which in turn equals to the @{term cp}-value of @{term th}. *} |
554 which equals to @{term "?R"} by simplification: *} |
513 also have "... = ?R" |
555 also have "... = ?R" |
514 using runing_preced_inversion[OF otherwise] th_kept by simp |
556 thm runing_preced_inversion |
|
557 using runing_preced_inversion[OF otherwise] by simp |
515 finally show ?thesis . |
558 finally show ?thesis . |
516 qed |
559 qed |
517 qed (auto simp: th'_in th_kept) |
560 qed (auto simp: th'_in th_kept) |
518 moreover have "th' \<noteq> th" using neq_th' . |
561 with `th' \<noteq> th` show ?thesis by simp |
519 ultimately show ?thesis by simp |
|
520 qed |
562 qed |
521 qed |
563 qed |
522 |
564 |
523 text {* |
565 text {* |
524 The following lemma is the extrapolation of @{thm eq_pv_blocked}. |
566 The following lemma is the extrapolation of @{thm eq_pv_blocked}. |
587 and eq_pv: "cntP s th' = cntV s th'" |
629 and eq_pv: "cntP s th' = cntV s th'" |
588 shows "th' \<notin> runing (t@s)" |
630 shows "th' \<notin> runing (t@s)" |
589 using assms |
631 using assms |
590 by (simp add: eq_pv_blocked eq_pv_persist) |
632 by (simp add: eq_pv_blocked eq_pv_persist) |
591 |
633 |
592 text {* |
|
593 The purpose of PIP is to ensure that the most |
|
594 urgent thread @{term th} is not blocked unreasonably. |
|
595 Therefore, a clear picture of the blocking thread is essential |
|
596 to assure people that the purpose is fulfilled. |
|
597 |
|
598 The following lemmas will give us such a picture: |
|
599 *} |
|
600 |
|
601 text {* |
634 text {* |
602 The following lemma shows the blocking thread @{term th'} |
635 The following lemma shows the blocking thread @{term th'} |
603 must hold some resource in the very beginning. |
636 must hold some resource in the very beginning. |
604 *} |
637 *} |
605 lemma runing_cntP_cntV_inv: (* ddd *) |
638 lemma runing_cntP_cntV_inv: (* ddd *) |