77 by (unfold vat_s.cp_rec, rule Max_ge, |
77 by (unfold vat_s.cp_rec, rule Max_ge, |
78 auto simp:the_preced_def vat_s.fsbttRAGs.finite_children) |
78 auto simp:the_preced_def vat_s.fsbttRAGs.finite_children) |
79 ultimately show ?thesis by auto |
79 ultimately show ?thesis by auto |
80 qed |
80 qed |
81 |
81 |
82 (* ccc *) |
|
83 lemma highest_cp_preced: "cp s th = Max ((\<lambda> th'. preced th' s) ` threads s)" |
82 lemma highest_cp_preced: "cp s th = Max ((\<lambda> th'. preced th' s) ` threads s)" |
84 by (fold max_cp_eq, unfold eq_cp_s_th, insert highest, simp) |
83 by (fold max_cp_eq, unfold eq_cp_s_th, insert highest, simp) |
85 |
84 |
86 lemma highest_preced_thread: "preced th s = Max ((\<lambda> th'. preced th' s) ` threads s)" |
85 lemma highest_preced_thread: "preced th s = Max ((\<lambda> th'. preced th' s) ` threads s)" |
87 by (fold eq_cp_s_th, unfold highest_cp_preced, simp) |
86 by (fold eq_cp_s_th, unfold highest_cp_preced, simp) |
132 |
131 |
133 sublocale red_extend_highest_gen < red_moment: extend_highest_gen "s" "th" "prio" "tm" "(moment i t)" |
132 sublocale red_extend_highest_gen < red_moment: extend_highest_gen "s" "th" "prio" "tm" "(moment i t)" |
134 apply (insert extend_highest_gen_axioms, subst (asm) (1) moment_restm_s [of i t, symmetric]) |
133 apply (insert extend_highest_gen_axioms, subst (asm) (1) moment_restm_s [of i t, symmetric]) |
135 apply (unfold extend_highest_gen_def extend_highest_gen_axioms_def, clarsimp) |
134 apply (unfold extend_highest_gen_def extend_highest_gen_axioms_def, clarsimp) |
136 by (unfold highest_gen_def, auto dest:step_back_vt_app) |
135 by (unfold highest_gen_def, auto dest:step_back_vt_app) |
137 |
|
138 |
136 |
139 context extend_highest_gen |
137 context extend_highest_gen |
140 begin |
138 begin |
141 |
139 |
142 lemma ind [consumes 0, case_names Nil Cons, induct type]: |
140 lemma ind [consumes 0, case_names Nil Cons, induct type]: |
456 by (metis Max.coboundedI finite_imageI highest not_le order.trans |
454 by (metis Max.coboundedI finite_imageI highest not_le order.trans |
457 preced_linorder rev_image_eqI threads_s vat_s.finite_threads |
455 preced_linorder rev_image_eqI threads_s vat_s.finite_threads |
458 vat_s.le_cp) |
456 vat_s.le_cp) |
459 |
457 |
460 text {* |
458 text {* |
|
459 The following lemmas shows that the @{term cp}-value |
|
460 of the blocking thread @{text th'} equals to the highest |
|
461 precedence in the whole system. |
|
462 *} |
|
463 lemma runing_preced_inversion: |
|
464 assumes runing': "th' \<in> runing (t@s)" |
|
465 shows "cp (t@s) th' = preced th s" (is "?L = ?R") |
|
466 proof - |
|
467 have "?L = Max (cp (t @ s) ` readys (t @ s))" using assms |
|
468 by (unfold runing_def, auto) |
|
469 also have "\<dots> = ?R" |
|
470 by (metis th_cp_max th_cp_preced vat_t.max_cp_readys_threads) |
|
471 finally show ?thesis . |
|
472 qed |
|
473 |
|
474 |
|
475 text {* |
461 Counting of the number of @{term "P"} and @{term "V"} operations |
476 Counting of the number of @{term "P"} and @{term "V"} operations |
462 is the cornerstone of a large number of the following proofs. |
477 is the cornerstone of a large number of the following proofs. |
463 The reason is that this counting is quite easy to calculate and |
478 The reason is that this counting is quite easy to calculate and |
464 convenient to use in the reasoning. |
479 convenient to use in the reasoning. |
465 |
480 |
466 The following lemma shows that the counting controls whether |
481 The following lemma shows that the counting controls whether |
467 a thread is running or not. |
482 a thread is running or not. |
468 *} |
483 *} (* ccc *) |
469 |
484 |
470 lemma pv_blocked_pre: (* ddd *) |
485 lemma eq_pv_blocked: (* ddd *) |
471 assumes th'_in: "th' \<in> threads (t@s)" |
486 assumes neq_th': "th' \<noteq> th" |
472 and neq_th': "th' \<noteq> th" |
|
473 and eq_pv: "cntP (t@s) th' = cntV (t@s) th'" |
487 and eq_pv: "cntP (t@s) th' = cntV (t@s) th'" |
474 shows "th' \<notin> runing (t@s)" |
488 shows "th' \<notin> runing (t@s)" |
475 proof |
489 proof |
476 assume otherwise: "th' \<in> runing (t@s)" |
490 assume otherwise: "th' \<in> runing (t@s)" |
477 show False |
491 show False |
478 proof - |
492 proof - |
|
493 have th'_in: "th' \<in> threads (t@s)" |
|
494 using otherwise readys_threads runing_def by auto |
479 have "th' = th" |
495 have "th' = th" |
480 proof(rule preced_unique) |
496 proof(rule preced_unique) |
|
497 -- {* The proof goes like this: |
|
498 it is first shown that the @{term preced}-value of @{term th'} |
|
499 equals to that of @{term th}, then by uniqueness |
|
500 of @{term preced}-values (given by lemma @{thm preced_unique}), |
|
501 @{term th'} equals to @{term th}: *} |
481 show "preced th' (t @ s) = preced th (t @ s)" (is "?L = ?R") |
502 show "preced th' (t @ s) = preced th (t @ s)" (is "?L = ?R") |
482 proof - |
503 proof - |
|
504 -- {* Since the counts of @{term th'} are balanced, the subtree |
|
505 of it contains only itself, so, its @{term cp}-value |
|
506 equals its @{term preced}-value: *} |
483 have "?L = cp (t@s) th'" |
507 have "?L = cp (t@s) th'" |
484 by (unfold cp_eq_cpreced cpreced_def count_eq_dependants[OF eq_pv], simp) |
508 by (unfold cp_eq_cpreced cpreced_def count_eq_dependants[OF eq_pv], simp) |
485 also have "... = cp (t @ s) th" using otherwise |
509 -- {* Since @{term "th'"} is running by @{thm otherwise}, |
486 by (metis (mono_tags, lifting) mem_Collect_eq |
510 it has the highest @{term cp}-value, by definition, |
487 runing_def th_cp_max vat_t.max_cp_readys_threads) |
511 which in turn equals to the @{term cp}-value of @{term th}. *} |
488 also have "... = ?R" by (metis th_cp_preced th_kept) |
512 also have "... = ?R" |
|
513 using runing_preced_inversion[OF otherwise] th_kept by simp |
489 finally show ?thesis . |
514 finally show ?thesis . |
490 qed |
515 qed |
491 qed (auto simp: th'_in th_kept) |
516 qed (auto simp: th'_in th_kept) |
492 moreover have "th' \<noteq> th" using neq_th' . |
517 moreover have "th' \<noteq> th" using neq_th' . |
493 ultimately show ?thesis by simp |
518 ultimately show ?thesis by simp |
494 qed |
519 qed |
495 qed |
520 qed |
496 |
521 |
497 lemmas pv_blocked = pv_blocked_pre[folded detached_eq] |
522 lemmas eq_pv_blocked_dtc = eq_pv_blocked[folded detached_eq] |
498 |
523 |
499 lemma runing_precond_pre: (* ddd *) |
524 |
500 fixes th' |
525 |
|
526 lemma eq_pv_kept: (* ddd *) |
501 assumes th'_in: "th' \<in> threads s" |
527 assumes th'_in: "th' \<in> threads s" |
502 and eq_pv: "cntP s th' = cntV s th'" |
528 and eq_pv: "cntP s th' = cntV s th'" |
503 and neq_th': "th' \<noteq> th" |
529 and neq_th': "th' \<noteq> th" |
504 shows "th' \<in> threads (t@s) \<and> |
530 shows "th' \<in> threads (t@s) \<and> |
505 cntP (t@s) th' = cntV (t@s) th'" |
531 cntP (t@s) th' = cntV (t@s) th'" |
594 case Nil |
620 case Nil |
595 with assms |
621 with assms |
596 show ?case by auto |
622 show ?case by auto |
597 qed |
623 qed |
598 |
624 |
|
625 (* runing_precond has changed to eq_pv_kept *) |
|
626 |
599 text {* Changing counting balance to detachedness *} |
627 text {* Changing counting balance to detachedness *} |
600 lemmas runing_precond_pre_dtc = runing_precond_pre |
628 lemmas eq_pv_kept_dtc = eq_pv_kept |
601 [folded vat_t.detached_eq vat_s.detached_eq] |
629 [folded vat_t.detached_eq vat_s.detached_eq] |
602 |
630 |
603 lemma runing_precond: (* ddd *) |
631 section {* The blocking thread *} |
604 fixes th' |
632 |
|
633 text {* |
|
634 The purpose of PIP is to ensure that the most |
|
635 urgent thread @{term th} is not blocked unreasonably. |
|
636 Therefore, a clear picture of the blocking thread is essential |
|
637 to assure people that the purpose is fulfilled. |
|
638 |
|
639 The following lemmas will give us such a picture: |
|
640 *} |
|
641 |
|
642 (* ccc *) |
|
643 |
|
644 text {* |
|
645 The following lemma shows the blocking thread @{term th'} |
|
646 must hold some resource in the very beginning. |
|
647 *} |
|
648 lemma runing_cntP_cntV_inv: (* ddd *) |
605 assumes th'_in: "th' \<in> threads s" |
649 assumes th'_in: "th' \<in> threads s" |
606 and neq_th': "th' \<noteq> th" |
650 and neq_th': "th' \<noteq> th" |
607 and is_runing: "th' \<in> runing (t@s)" |
651 and is_runing: "th' \<in> runing (t@s)" |
608 shows "cntP s th' > cntV s th'" |
652 shows "cntP s th' > cntV s th'" |
609 using assms |
653 using assms |
610 proof - |
654 proof - (* ccc *) |
|
655 -- {* First, it can be shown that the number of @{term P} and |
|
656 @{term V} operations can not be equal for thred @{term th'} *} |
611 have "cntP s th' \<noteq> cntV s th'" |
657 have "cntP s th' \<noteq> cntV s th'" |
612 by (metis is_runing neq_th' pv_blocked_pre runing_precond_pre th'_in) |
658 proof |
|
659 assume otherwise: "cntP s th' = cntV s th'" |
|
660 -- {* The proof goes by contradiction. *} |
|
661 -- {* We can show that @{term th'} can not be running at moment @{term "t@s"}: *} |
|
662 have "th' \<notin> runing (t@s)" |
|
663 proof(rule eq_pv_blocked) |
|
664 show "th' \<noteq> th" using neq_th' by simp |
|
665 next |
|
666 show "cntP (t @ s) th' = cntV (t @ s) th'" |
|
667 using eq_pv_kept[OF th'_in otherwise neq_th'] by simp |
|
668 qed |
|
669 -- {* This is obvious in contradiction with assumption @{thm is_runing} *} |
|
670 thus False using is_runing by simp |
|
671 qed |
613 moreover have "cntV s th' \<le> cntP s th'" using vat_s.cnp_cnv_cncs by auto |
672 moreover have "cntV s th' \<le> cntP s th'" using vat_s.cnp_cnv_cncs by auto |
614 ultimately show ?thesis by auto |
673 ultimately show ?thesis by auto |
615 qed |
674 qed |
616 |
675 |
617 lemma moment_blocked_pre: |
676 lemma moment_blocked_pre: |
674 and h2: "th' \<in> threads ((moment j t)@s)" by auto |
733 and h2: "th' \<in> threads ((moment j t)@s)" by auto |
675 moreover have "th' \<notin> runing ((moment j t)@s)" |
734 moreover have "th' \<notin> runing ((moment j t)@s)" |
676 proof - |
735 proof - |
677 interpret h: red_extend_highest_gen _ _ _ _ _ j by (unfold_locales) |
736 interpret h: red_extend_highest_gen _ _ _ _ _ j by (unfold_locales) |
678 show ?thesis |
737 show ?thesis |
679 using h.pv_blocked_pre h1 h2 neq_th' by auto |
738 using h.eq_pv_blocked h1 h2 neq_th' by auto |
680 qed |
739 qed |
681 ultimately show ?thesis by auto |
740 ultimately show ?thesis by auto |
682 qed |
741 qed |
683 |
742 |
684 (* The foregoing two lemmas are preparation for this one, but |
743 (* The foregoing two lemmas are preparation for this one, but |
685 in long run can be combined. Maybe I am wrong. |
744 in long run can be combined. Maybe I am wrong. |
|
745 This one is useless (* XY *) |
686 *) |
746 *) |
687 lemma moment_blocked: |
747 lemma moment_blocked: |
688 assumes neq_th': "th' \<noteq> th" |
748 assumes neq_th': "th' \<noteq> th" |
689 and th'_in: "th' \<in> threads ((moment i t)@s)" |
749 and th'_in: "th' \<in> threads ((moment i t)@s)" |
690 and dtc: "detached (moment i t @ s) th'" |
750 and dtc: "detached (moment i t @ s) th'" |
699 by (metis dtc h_i.detached_elim) |
759 by (metis dtc h_i.detached_elim) |
700 from moment_blocked_eqpv[OF neq_th' th'_in cnt_i le_ij] |
760 from moment_blocked_eqpv[OF neq_th' th'_in cnt_i le_ij] |
701 show ?thesis by (metis h_j.detached_intro) |
761 show ?thesis by (metis h_j.detached_intro) |
702 qed |
762 qed |
703 |
763 |
704 lemma runing_preced_inversion: |
764 text {* |
|
765 The following lemmas shows the blocking thread @{text th'} must be live |
|
766 at the very beginning, i.e. the moment (or state) @{term s}. |
|
767 *} |
|
768 lemma runing_threads_inv: (* ddd *) (* ccc *) |
705 assumes runing': "th' \<in> runing (t@s)" |
769 assumes runing': "th' \<in> runing (t@s)" |
706 shows "cp (t@s) th' = preced th s" (is "?L = ?R") |
770 and neq_th': "th' \<noteq> th" |
707 proof - |
|
708 have "?L = Max (cp (t @ s) ` readys (t @ s))" using assms |
|
709 by (unfold runing_def, auto) |
|
710 also have "\<dots> = ?R" |
|
711 by (metis th_cp_max th_cp_preced vat_t.max_cp_readys_threads) |
|
712 finally show ?thesis . |
|
713 qed |
|
714 |
|
715 text {* |
|
716 The situation when @{term "th"} is blocked is analyzed by the following lemmas. |
|
717 *} |
|
718 |
|
719 text {* |
|
720 The following lemmas shows the running thread @{text "th'"}, if it is different from |
|
721 @{term th}, must be live at the very beginning. By the term {\em the very beginning}, |
|
722 we mean the moment where the formal investigation starts, i.e. the moment (or state) |
|
723 @{term s}. |
|
724 *} |
|
725 |
|
726 lemma runing_inversion_0: |
|
727 assumes neq_th': "th' \<noteq> th" |
|
728 and runing': "th' \<in> runing (t@s)" |
|
729 shows "th' \<in> threads s" |
771 shows "th' \<in> threads s" |
730 proof - |
772 proof - |
731 -- {* The proof is by contradiction: *} |
773 -- {* The proof is by contradiction: *} |
732 { assume otherwise: "\<not> ?thesis" |
774 { assume otherwise: "\<not> ?thesis" |
733 have "th' \<notin> runing (t @ s)" |
775 have "th' \<notin> runing (t @ s)" |
772 with `th' \<in> runing (t@s)` |
814 with `th' \<in> runing (t@s)` |
773 have False by simp |
815 have False by simp |
774 } thus ?thesis by auto |
816 } thus ?thesis by auto |
775 qed |
817 qed |
776 |
818 |
777 text {* |
819 text {* |
778 The second lemma says, if the running thread @{text th'} is different from |
820 The following lemma summarizes several foregoing |
779 @{term th}, then this @{text th'} must in the possession of some resources |
821 lemmas to give an overall picture of the blocking thread @{text "th'"}: |
780 at the very beginning. |
822 *} |
781 |
823 lemma runing_inversion: |
782 To ease the reasoning of resource possession of one particular thread, |
|
783 we used two auxiliary functions @{term cntV} and @{term cntP}, |
|
784 which are the counters of @{term P}-operations and |
|
785 @{term V}-operations respectively. |
|
786 If the number of @{term V}-operation is less than the number of |
|
787 @{term "P"}-operations, the thread must have some unreleased resource. |
|
788 *} |
|
789 |
|
790 lemma runing_inversion_1: (* ddd *) |
|
791 assumes neq_th': "th' \<noteq> th" |
|
792 and runing': "th' \<in> runing (t@s)" |
|
793 -- {* thread @{term "th'"} is a live on in state @{term "s"} and |
|
794 it has some unreleased resource. *} |
|
795 shows "th' \<in> threads s \<and> cntV s th' < cntP s th'" |
|
796 proof - |
|
797 -- {* The proof is a simple composition of @{thm runing_inversion_0} and |
|
798 @{thm runing_precond}: *} |
|
799 -- {* By applying @{thm runing_inversion_0} to assumptions, |
|
800 it can be shown that @{term th'} is live in state @{term s}: *} |
|
801 have "th' \<in> threads s" using runing_inversion_0[OF assms(1,2)] . |
|
802 -- {* Then the thesis is derived easily by applying @{thm runing_precond}: *} |
|
803 with runing_precond [OF this neq_th' runing'] show ?thesis by simp |
|
804 qed |
|
805 |
|
806 text {* |
|
807 The following lemma is just a rephrasing of @{thm runing_inversion_1}: |
|
808 *} |
|
809 lemma runing_inversion_2: |
|
810 assumes runing': "th' \<in> runing (t@s)" |
|
811 shows "th' = th \<or> (th' \<noteq> th \<and> th' \<in> threads s \<and> cntV s th' < cntP s th')" |
|
812 proof - |
|
813 from runing_inversion_1[OF _ runing'] |
|
814 show ?thesis by auto |
|
815 qed |
|
816 |
|
817 lemma runing_inversion_3: |
|
818 assumes runing': "th' \<in> runing (t@s)" |
|
819 and neq_th: "th' \<noteq> th" |
|
820 shows "th' \<in> threads s \<and> (cntV s th' < cntP s th' \<and> cp (t@s) th' = preced th s)" |
|
821 by (metis neq_th runing' runing_inversion_2 runing_preced_inversion) |
|
822 |
|
823 lemma runing_inversion_4: |
|
824 assumes runing': "th' \<in> runing (t@s)" |
824 assumes runing': "th' \<in> runing (t@s)" |
825 and neq_th: "th' \<noteq> th" |
825 and neq_th: "th' \<noteq> th" |
826 shows "th' \<in> threads s" |
826 shows "th' \<in> threads s" |
827 and "\<not>detached s th'" |
827 and "\<not>detached s th'" |
828 and "cp (t@s) th' = preced th s" |
828 and "cp (t@s) th' = preced th s" |
829 apply (metis neq_th runing' runing_inversion_2) |
829 proof - |
830 apply (metis neq_th pv_blocked runing' runing_inversion_2 runing_precond_pre_dtc) |
830 from runing_threads_inv[OF assms] |
831 by (metis neq_th runing' runing_inversion_3) |
831 show "th' \<in> threads s" . |
|
832 next |
|
833 from runing_cntP_cntV_inv[OF runing_threads_inv[OF assms] neq_th runing'] |
|
834 show "\<not>detached s th'" using vat_s.detached_eq by simp |
|
835 next |
|
836 from runing_preced_inversion[OF runing'] |
|
837 show "cp (t@s) th' = preced th s" . |
|
838 qed |
832 |
839 |
833 text {* |
840 text {* |
834 Suppose @{term th} is not running, it is first shown that |
841 Suppose @{term th} is not running, it is first shown that |
835 there is a path in RAG leading from node @{term th} to another thread @{text "th'"} |
842 there is a path in RAG leading from node @{term th} to another thread @{text "th'"} |
836 in the @{term readys}-set (So @{text "th'"} is an ancestor of @{term th}}). |
843 in the @{term readys}-set (So @{text "th'"} is an ancestor of @{term th}}). |