496 text {* |
496 text {* |
497 The following lemmas shows that the @{term cp}-value |
497 The following lemmas shows that the @{term cp}-value |
498 of the blocking thread @{text th'} equals to the highest |
498 of the blocking thread @{text th'} equals to the highest |
499 precedence in the whole system. |
499 precedence in the whole system. |
500 *} |
500 *} |
501 lemma runing_preced_inversion: |
501 lemma running_preced_inversion: |
502 assumes runing': "th' \<in> runing (t@s)" |
502 assumes running': "th' \<in> running (t@s)" |
503 shows "cp (t@s) th' = preced th s" (is "?L = ?R") |
503 shows "cp (t@s) th' = preced th s" (is "?L = ?R") |
504 proof - |
504 proof - |
505 have "?L = Max (cp (t @ s) ` readys (t @ s))" using assms |
505 have "?L = Max (cp (t @ s) ` readys (t @ s))" using assms |
506 by (unfold runing_def, auto) |
506 by (unfold running_def, auto) |
507 also have "\<dots> = ?R" |
507 also have "\<dots> = ?R" |
508 by (metis th_cp_max th_cp_preced vat_t.max_cp_readys_threads) |
508 by (metis th_cp_max th_cp_preced vat_t.max_cp_readys_threads) |
509 finally show ?thesis . |
509 finally show ?thesis . |
510 qed |
510 qed |
511 |
511 |
523 emptiness of @{text th'}s @{term dependants}-set from the balance of |
523 emptiness of @{text th'}s @{term dependants}-set from the balance of |
524 its @{term P} and @{term V} counts. From this, it can be shown |
524 its @{term P} and @{term V} counts. From this, it can be shown |
525 @{text th'}s @{term cp}-value equals to its own precedence. |
525 @{text th'}s @{term cp}-value equals to its own precedence. |
526 |
526 |
527 On the other hand, since @{text th'} is running, by @{thm |
527 On the other hand, since @{text th'} is running, by @{thm |
528 runing_preced_inversion}, its @{term cp}-value equals to the |
528 running_preced_inversion}, its @{term cp}-value equals to the |
529 precedence of @{term th}. |
529 precedence of @{term th}. |
530 |
530 |
531 Combining the above two resukts we have that @{text th'} and @{term |
531 Combining the above two resukts we have that @{text th'} and @{term |
532 th} have the same precedence. By uniqueness of precedences, we have |
532 th} have the same precedence. By uniqueness of precedences, we have |
533 @{text "th' = th"}, which is in contradiction with the assumption |
533 @{text "th' = th"}, which is in contradiction with the assumption |
536 *} |
536 *} |
537 |
537 |
538 lemma eq_pv_blocked: (* ddd *) |
538 lemma eq_pv_blocked: (* ddd *) |
539 assumes neq_th': "th' \<noteq> th" |
539 assumes neq_th': "th' \<noteq> th" |
540 and eq_pv: "cntP (t@s) th' = cntV (t@s) th'" |
540 and eq_pv: "cntP (t@s) th' = cntV (t@s) th'" |
541 shows "th' \<notin> runing (t@s)" |
541 shows "th' \<notin> running (t@s)" |
542 proof |
542 proof |
543 assume otherwise: "th' \<in> runing (t@s)" |
543 assume otherwise: "th' \<in> running (t@s)" |
544 show False |
544 show False |
545 proof - |
545 proof - |
546 have th'_in: "th' \<in> threads (t@s)" |
546 have th'_in: "th' \<in> threads (t@s)" |
547 using otherwise readys_threads runing_def by auto |
547 using otherwise readys_threads running_def by auto |
548 have "th' = th" |
548 have "th' = th" |
549 proof(rule preced_unique) |
549 proof(rule preced_unique) |
550 -- {* The proof goes like this: |
550 -- {* The proof goes like this: |
551 it is first shown that the @{term preced}-value of @{term th'} |
551 it is first shown that the @{term preced}-value of @{term th'} |
552 equals to that of @{term th}, then by uniqueness |
552 equals to that of @{term th}, then by uniqueness |
557 -- {* Since the counts of @{term th'} are balanced, the subtree |
557 -- {* Since the counts of @{term th'} are balanced, the subtree |
558 of it contains only itself, so, its @{term cp}-value |
558 of it contains only itself, so, its @{term cp}-value |
559 equals its @{term preced}-value: *} |
559 equals its @{term preced}-value: *} |
560 have "?L = cp (t@s) th'" |
560 have "?L = cp (t@s) th'" |
561 by (unfold cp_eq cpreced_def eq_dependants vat_t.eq_pv_dependants[OF eq_pv], simp) |
561 by (unfold cp_eq cpreced_def eq_dependants vat_t.eq_pv_dependants[OF eq_pv], simp) |
562 -- {* Since @{term "th'"} is running, by @{thm runing_preced_inversion}, |
562 -- {* Since @{term "th'"} is running, by @{thm running_preced_inversion}, |
563 its @{term cp}-value equals @{term "preced th s"}, |
563 its @{term cp}-value equals @{term "preced th s"}, |
564 which equals to @{term "?R"} by simplification: *} |
564 which equals to @{term "?R"} by simplification: *} |
565 also have "... = ?R" |
565 also have "... = ?R" |
566 thm runing_preced_inversion |
566 thm running_preced_inversion |
567 using runing_preced_inversion[OF otherwise] by simp |
567 using running_preced_inversion[OF otherwise] by simp |
568 finally show ?thesis . |
568 finally show ?thesis . |
569 qed |
569 qed |
570 qed (auto simp: th'_in th_kept) |
570 qed (auto simp: th'_in th_kept) |
571 with `th' \<noteq> th` show ?thesis by simp |
571 with `th' \<noteq> th` show ?thesis by simp |
572 qed |
572 qed |
598 -- {* Suppose @{term cntP}-value of @{term th'} is changed by @{term e}: *} |
598 -- {* Suppose @{term cntP}-value of @{term th'} is changed by @{term e}: *} |
599 assume otherwise: "cntP ((e # t) @ s) th' \<noteq> cntP (t @ s) th'" |
599 assume otherwise: "cntP ((e # t) @ s) th' \<noteq> cntP (t @ s) th'" |
600 from cntP_diff_inv[OF this[simplified]] |
600 from cntP_diff_inv[OF this[simplified]] |
601 obtain cs' where "e = P th' cs'" by auto |
601 obtain cs' where "e = P th' cs'" by auto |
602 from vat_es.pip_e[unfolded this] |
602 from vat_es.pip_e[unfolded this] |
603 have "th' \<in> runing (t@s)" |
603 have "th' \<in> running (t@s)" |
604 by (cases, simp) |
604 by (cases, simp) |
605 -- {* However, an application of @{thm eq_pv_blocked} to induction hypothesis |
605 -- {* However, an application of @{thm eq_pv_blocked} to induction hypothesis |
606 shows @{term th'} can not be running at moment @{term "t@s"}: *} |
606 shows @{term th'} can not be running at moment @{term "t@s"}: *} |
607 moreover have "th' \<notin> runing (t@s)" |
607 moreover have "th' \<notin> running (t@s)" |
608 using vat_t.eq_pv_blocked[OF neq_th' Cons(5)] . |
608 using vat_t.eq_pv_blocked[OF neq_th' Cons(5)] . |
609 -- {* Contradiction is finally derived: *} |
609 -- {* Contradiction is finally derived: *} |
610 ultimately show False by simp |
610 ultimately show False by simp |
611 qed |
611 qed |
612 -- {* It can also be proved that @{term cntV}-value of @{term th'} does not change |
612 -- {* It can also be proved that @{term cntV}-value of @{term th'} does not change |
616 proof(rule ccontr) -- {* Proof by contradiction. *} |
616 proof(rule ccontr) -- {* Proof by contradiction. *} |
617 assume otherwise: "cntV ((e # t) @ s) th' \<noteq> cntV (t @ s) th'" |
617 assume otherwise: "cntV ((e # t) @ s) th' \<noteq> cntV (t @ s) th'" |
618 from cntV_diff_inv[OF this[simplified]] |
618 from cntV_diff_inv[OF this[simplified]] |
619 obtain cs' where "e = V th' cs'" by auto |
619 obtain cs' where "e = V th' cs'" by auto |
620 from vat_es.pip_e[unfolded this] |
620 from vat_es.pip_e[unfolded this] |
621 have "th' \<in> runing (t@s)" by (cases, auto) |
621 have "th' \<in> running (t@s)" by (cases, auto) |
622 moreover have "th' \<notin> runing (t@s)" |
622 moreover have "th' \<notin> running (t@s)" |
623 using vat_t.eq_pv_blocked[OF neq_th' Cons(5)] . |
623 using vat_t.eq_pv_blocked[OF neq_th' Cons(5)] . |
624 ultimately show False by simp |
624 ultimately show False by simp |
625 qed |
625 qed |
626 -- {* Finally, it can be shown that the @{term cntP} and @{term cntV} |
626 -- {* Finally, it can be shown that the @{term cntP} and @{term cntV} |
627 value for @{term th'} are still in balance, so @{term th'} |
627 value for @{term th'} are still in balance, so @{term th'} |
635 it can be derived easily that @{term th'} can not be running in the future: |
635 it can be derived easily that @{term th'} can not be running in the future: |
636 *} |
636 *} |
637 lemma eq_pv_blocked_persist: |
637 lemma eq_pv_blocked_persist: |
638 assumes neq_th': "th' \<noteq> th" |
638 assumes neq_th': "th' \<noteq> th" |
639 and eq_pv: "cntP s th' = cntV s th'" |
639 and eq_pv: "cntP s th' = cntV s th'" |
640 shows "th' \<notin> runing (t@s)" |
640 shows "th' \<notin> running (t@s)" |
641 using assms |
641 using assms |
642 by (simp add: eq_pv_blocked eq_pv_persist) |
642 by (simp add: eq_pv_blocked eq_pv_persist) |
643 |
643 |
644 text {* |
644 text {* |
645 The following lemma shows the blocking thread @{term th'} |
645 The following lemma shows the blocking thread @{term th'} |
646 must hold some resource in the very beginning. |
646 must hold some resource in the very beginning. |
647 *} |
647 *} |
648 lemma runing_cntP_cntV_inv: (* ddd *) |
648 lemma running_cntP_cntV_inv: (* ddd *) |
649 assumes is_runing: "th' \<in> runing (t@s)" |
649 assumes is_running: "th' \<in> running (t@s)" |
650 and neq_th': "th' \<noteq> th" |
650 and neq_th': "th' \<noteq> th" |
651 shows "cntP s th' > cntV s th'" |
651 shows "cntP s th' > cntV s th'" |
652 using assms |
652 using assms |
653 proof - |
653 proof - |
654 -- {* First, it can be shown that the number of @{term P} and |
654 -- {* First, it can be shown that the number of @{term P} and |
658 -- {* The proof goes by contradiction, suppose otherwise: *} |
658 -- {* The proof goes by contradiction, suppose otherwise: *} |
659 assume otherwise: "cntP s th' = cntV s th'" |
659 assume otherwise: "cntP s th' = cntV s th'" |
660 -- {* By applying @{thm eq_pv_blocked_persist} to this: *} |
660 -- {* By applying @{thm eq_pv_blocked_persist} to this: *} |
661 from eq_pv_blocked_persist[OF neq_th' otherwise] |
661 from eq_pv_blocked_persist[OF neq_th' otherwise] |
662 -- {* we have that @{term th'} can not be running at moment @{term "t@s"}: *} |
662 -- {* we have that @{term th'} can not be running at moment @{term "t@s"}: *} |
663 have "th' \<notin> runing (t@s)" . |
663 have "th' \<notin> running (t@s)" . |
664 -- {* This is obvious in contradiction with assumption @{thm is_runing} *} |
664 -- {* This is obvious in contradiction with assumption @{thm is_running} *} |
665 thus False using is_runing by simp |
665 thus False using is_running by simp |
666 qed |
666 qed |
667 -- {* However, the number of @{term V} is always less or equal to @{term P}: *} |
667 -- {* However, the number of @{term V} is always less or equal to @{term P}: *} |
668 moreover have "cntV s th' \<le> cntP s th'" using vat_s.cnp_cnv_cncs by auto |
668 moreover have "cntV s th' \<le> cntP s th'" using vat_s.cnp_cnv_cncs by auto |
669 -- {* Thesis is finally derived by combining the these two results: *} |
669 -- {* Thesis is finally derived by combining the these two results: *} |
670 ultimately show ?thesis by auto |
670 ultimately show ?thesis by auto |
675 The following lemmas shows the blocking thread @{text th'} must be live |
675 The following lemmas shows the blocking thread @{text th'} must be live |
676 at the very beginning, i.e. the moment (or state) @{term s}. |
676 at the very beginning, i.e. the moment (or state) @{term s}. |
677 |
677 |
678 The proof is a simple combination of the results above: |
678 The proof is a simple combination of the results above: |
679 *} |
679 *} |
680 lemma runing_threads_inv: |
680 lemma running_threads_inv: |
681 assumes runing': "th' \<in> runing (t@s)" |
681 assumes running': "th' \<in> running (t@s)" |
682 and neq_th': "th' \<noteq> th" |
682 and neq_th': "th' \<noteq> th" |
683 shows "th' \<in> threads s" |
683 shows "th' \<in> threads s" |
684 proof(rule ccontr) -- {* Proof by contradiction: *} |
684 proof(rule ccontr) -- {* Proof by contradiction: *} |
685 assume otherwise: "th' \<notin> threads s" |
685 assume otherwise: "th' \<notin> threads s" |
686 have "th' \<notin> runing (t @ s)" |
686 have "th' \<notin> running (t @ s)" |
687 proof - |
687 proof - |
688 from vat_s.cnp_cnv_eq[OF otherwise] |
688 from vat_s.cnp_cnv_eq[OF otherwise] |
689 have "cntP s th' = cntV s th'" . |
689 have "cntP s th' = cntV s th'" . |
690 from eq_pv_blocked_persist[OF neq_th' this] |
690 from eq_pv_blocked_persist[OF neq_th' this] |
691 show ?thesis . |
691 show ?thesis . |
692 qed |
692 qed |
693 with runing' show False by simp |
693 with running' show False by simp |
694 qed |
694 qed |
695 |
695 |
696 text {* |
696 text {* |
697 The following lemma summarizes several foregoing |
697 The following lemma summarizes several foregoing |
698 lemmas to give an overall picture of the blocking thread @{text "th'"}: |
698 lemmas to give an overall picture of the blocking thread @{text "th'"}: |
699 *} |
699 *} |
700 lemma runing_inversion: (* ddd, one of the main lemmas to present *) |
700 lemma running_inversion: (* ddd, one of the main lemmas to present *) |
701 assumes runing': "th' \<in> runing (t@s)" |
701 assumes running': "th' \<in> running (t@s)" |
702 and neq_th: "th' \<noteq> th" |
702 and neq_th: "th' \<noteq> th" |
703 shows "th' \<in> threads s" |
703 shows "th' \<in> threads s" |
704 and "\<not>detached s th'" |
704 and "\<not>detached s th'" |
705 and "cp (t@s) th' = preced th s" |
705 and "cp (t@s) th' = preced th s" |
706 proof - |
706 proof - |
707 from runing_threads_inv[OF assms] |
707 from running_threads_inv[OF assms] |
708 show "th' \<in> threads s" . |
708 show "th' \<in> threads s" . |
709 next |
709 next |
710 from runing_cntP_cntV_inv[OF runing' neq_th] |
710 from running_cntP_cntV_inv[OF running' neq_th] |
711 show "\<not>detached s th'" using vat_s.detached_eq by simp |
711 show "\<not>detached s th'" using vat_s.detached_eq by simp |
712 next |
712 next |
713 from runing_preced_inversion[OF runing'] |
713 from running_preced_inversion[OF running'] |
714 show "cp (t@s) th' = preced th s" . |
714 show "cp (t@s) th' = preced th s" . |
715 qed |
715 qed |
716 |
716 |
717 section {* The existence of `blocking thread` *} |
717 section {* The existence of `blocking thread` *} |
718 |
718 |
721 there is a path in RAG leading from node @{term th} to another thread @{text "th'"} |
721 there is a path in RAG leading from node @{term th} to another thread @{text "th'"} |
722 in the @{term readys}-set (So @{text "th'"} is an ancestor of @{term th}}). |
722 in the @{term readys}-set (So @{text "th'"} is an ancestor of @{term th}}). |
723 |
723 |
724 Now, since @{term readys}-set is non-empty, there must be |
724 Now, since @{term readys}-set is non-empty, there must be |
725 one in it which holds the highest @{term cp}-value, which, by definition, |
725 one in it which holds the highest @{term cp}-value, which, by definition, |
726 is the @{term runing}-thread. However, we are going to show more: this running thread |
726 is the @{term running}-thread. However, we are going to show more: this running thread |
727 is exactly @{term "th'"}. |
727 is exactly @{term "th'"}. |
728 *} |
728 *} |
729 lemma th_blockedE: (* ddd, the other main lemma to be presented: *) |
729 lemma th_blockedE: (* ddd, the other main lemma to be presented: *) |
730 assumes "th \<notin> runing (t@s)" |
730 assumes "th \<notin> running (t@s)" |
731 obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
731 obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
732 "th' \<in> runing (t@s)" |
732 "th' \<in> running (t@s)" |
733 proof - |
733 proof - |
734 -- {* According to @{thm vat_t.th_chain_to_ready}, either |
734 -- {* According to @{thm vat_t.th_chain_to_ready}, either |
735 @{term "th"} is in @{term "readys"} or there is path leading from it to |
735 @{term "th"} is in @{term "readys"} or there is path leading from it to |
736 one thread in @{term "readys"}. *} |
736 one thread in @{term "readys"}. *} |
737 have "th \<in> readys (t @ s) \<or> (\<exists>th'. th' \<in> readys (t @ s) \<and> (Th th, Th th') \<in> (RAG (t @ s))\<^sup>+)" |
737 have "th \<in> readys (t @ s) \<or> (\<exists>th'. th' \<in> readys (t @ s) \<and> (Th th, Th th') \<in> (RAG (t @ s))\<^sup>+)" |
738 using th_kept vat_t.th_chain_to_ready by auto |
738 using th_kept vat_t.th_chain_to_ready by auto |
739 -- {* However, @{term th} can not be in @{term readys}, because otherwise, since |
739 -- {* However, @{term th} can not be in @{term readys}, because otherwise, since |
740 @{term th} holds the highest @{term cp}-value, it must be @{term "runing"}. *} |
740 @{term th} holds the highest @{term cp}-value, it must be @{term "running"}. *} |
741 moreover have "th \<notin> readys (t@s)" |
741 moreover have "th \<notin> readys (t@s)" |
742 using assms runing_def th_cp_max vat_t.max_cp_readys_threads by auto |
742 using assms running_def th_cp_max vat_t.max_cp_readys_threads by auto |
743 -- {* So, there must be a path from @{term th} to another thread @{text "th'"} in |
743 -- {* So, there must be a path from @{term th} to another thread @{text "th'"} in |
744 term @{term readys}: *} |
744 term @{term readys}: *} |
745 ultimately obtain th' where th'_in: "th' \<in> readys (t@s)" |
745 ultimately obtain th' where th'_in: "th' \<in> readys (t@s)" |
746 and dp: "(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+" by auto |
746 and dp: "(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+" by auto |
747 -- {* We are going to show that this @{term th'} is running. *} |
747 -- {* We are going to show that this @{term th'} is running. *} |
748 have "th' \<in> runing (t@s)" |
748 have "th' \<in> running (t@s)" |
749 proof - |
749 proof - |
750 -- {* We only need to show that this @{term th'} holds the highest @{term cp}-value: *} |
750 -- {* We only need to show that this @{term th'} holds the highest @{term cp}-value: *} |
751 have "cp (t@s) th' = Max (cp (t@s) ` readys (t@s))" (is "?L = ?R") |
751 have "cp (t@s) th' = Max (cp (t@s) ` readys (t@s))" (is "?L = ?R") |
752 proof - |
752 proof - |
753 -- {* First, by the alternative definition of @{term cp} (I mean @{thm cp_alt_def1}), |
753 -- {* First, by the alternative definition of @{term cp} (I mean @{thm cp_alt_def1}), |
781 the_preced_def vat_t.max_cp_readys_threads |
781 the_preced_def vat_t.max_cp_readys_threads |
782 finally show ?thesis . |
782 finally show ?thesis . |
783 qed |
783 qed |
784 -- {* Now, since @{term th'} holds the highest @{term cp} |
784 -- {* Now, since @{term th'} holds the highest @{term cp} |
785 and we have already show it is in @{term readys}, |
785 and we have already show it is in @{term readys}, |
786 it is @{term runing} by definition. *} |
786 it is @{term running} by definition. *} |
787 with `th' \<in> readys (t@s)` show ?thesis by (simp add: runing_def) |
787 with `th' \<in> readys (t@s)` show ?thesis by (simp add: running_def) |
788 qed |
788 qed |
789 -- {* It is easy to show @{term th'} is an ancestor of @{term th}: *} |
789 -- {* It is easy to show @{term th'} is an ancestor of @{term th}: *} |
790 moreover have "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
790 moreover have "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
791 using `(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+` by (auto simp:ancestors_def) |
791 using `(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+` by (auto simp:ancestors_def) |
792 ultimately show ?thesis using that by metis |
792 ultimately show ?thesis using that by metis |
793 qed |
793 qed |
794 |
794 |
795 lemma (* new proof of th_blockedE *) |
795 lemma (* new proof of th_blockedE *) |
796 assumes "th \<notin> runing (t @ s)" |
796 assumes "th \<notin> running (t @ s)" |
797 obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
797 obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
798 "th' \<in> runing (t @ s)" |
798 "th' \<in> running (t @ s)" |
799 proof - |
799 proof - |
800 |
800 |
801 -- {* According to @{thm vat_t.th_chain_to_ready}, either @{term "th"} is |
801 -- {* According to @{thm vat_t.th_chain_to_ready}, either @{term "th"} is |
802 in @{term "readys"} or there is path in the @{term RAG} leading from |
802 in @{term "readys"} or there is path in the @{term RAG} leading from |
803 it to a thread that is in @{term "readys"}. However, @{term th} cannot |
803 it to a thread that is in @{term "readys"}. However, @{term th} cannot |
804 be in @{term readys}, because otherwise, since @{term th} holds the |
804 be in @{term readys}, because otherwise, since @{term th} holds the |
805 highest @{term cp}-value, it must be @{term "runing"}. This would |
805 highest @{term cp}-value, it must be @{term "running"}. This would |
806 violate our assumption. *} |
806 violate our assumption. *} |
807 have "th \<notin> readys (t @ s)" |
807 have "th \<notin> readys (t @ s)" |
808 using assms runing_def th_cp_max vat_t.max_cp_readys_threads by auto |
808 using assms running_def th_cp_max vat_t.max_cp_readys_threads by auto |
809 then have "\<exists>th'. th' \<in> readys (t @ s) \<and> (Th th, Th th') \<in> (RAG (t @ s))\<^sup>+" |
809 then have "\<exists>th'. th' \<in> readys (t @ s) \<and> (Th th, Th th') \<in> (RAG (t @ s))\<^sup>+" |
810 using th_kept vat_t.th_chain_to_ready by auto |
810 using th_kept vat_t.th_chain_to_ready by auto |
811 then obtain th' where th'_in: "th' \<in> readys (t@s)" |
811 then obtain th' where th'_in: "th' \<in> readys (t@s)" |
812 and dp: "(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+" by auto |
812 and dp: "(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+" by auto |
813 |
813 |
814 -- {* We are going to first show that this @{term th'} is running. *} |
814 -- {* We are going to first show that this @{term th'} is running. *} |
815 have "th' \<in> runing (t @ s)" |
815 have "th' \<in> running (t @ s)" |
816 proof - |
816 proof - |
817 -- {* For this we need to show that @{term th'} holds the highest @{term cp}-value: *} |
817 -- {* For this we need to show that @{term th'} holds the highest @{term cp}-value: *} |
818 have "cp (t @ s) th' = Max (cp (t @ s) ` readys (t @ s))" (is "?L = ?R") |
818 have "cp (t @ s) th' = Max (cp (t @ s) ` readys (t @ s))" (is "?L = ?R") |
819 proof - |
819 proof - |
820 -- {* First, by the alternative definition of @{term cp} (I mean @{thm cp_alt_def1}), |
820 -- {* First, by the alternative definition of @{term cp} (I mean @{thm cp_alt_def1}), |
850 the_preced_def vat_t.max_cp_readys_threads by auto |
850 the_preced_def vat_t.max_cp_readys_threads by auto |
851 finally show "cp (t @ s) th' = Max (cp (t @ s) ` readys (t @ s))" . |
851 finally show "cp (t @ s) th' = Max (cp (t @ s) ` readys (t @ s))" . |
852 qed |
852 qed |
853 |
853 |
854 -- {* Now, since @{term th'} holds the highest @{term cp}-value in readys, |
854 -- {* Now, since @{term th'} holds the highest @{term cp}-value in readys, |
855 it is @{term runing} by definition. *} |
855 it is @{term running} by definition. *} |
856 with `th' \<in> readys (t @ s)` show "th' \<in> runing (t @ s)" by (simp add: runing_def) |
856 with `th' \<in> readys (t @ s)` show "th' \<in> running (t @ s)" by (simp add: running_def) |
857 qed |
857 qed |
858 |
858 |
859 -- {* It is easy to show @{term th'} is an ancestor of @{term th}: *} |
859 -- {* It is easy to show @{term th'} is an ancestor of @{term th}: *} |
860 moreover have "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
860 moreover have "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
861 using `(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+` by (auto simp:ancestors_def) |
861 using `(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+` by (auto simp:ancestors_def) |
862 ultimately show ?thesis using that by metis |
862 ultimately show ?thesis using that by metis |
863 qed |
863 qed |
864 |
864 |
865 lemma th_blockedE_pretty: |
865 lemma th_blockedE_pretty: |
866 assumes "th \<notin> runing (t@s)" |
866 assumes "th \<notin> running (t@s)" |
867 shows "\<exists>th'. Th th' \<in> ancestors (RAG (t @ s)) (Th th) \<and> th' \<in> runing (t@s)" |
867 shows "\<exists>th'. Th th' \<in> ancestors (RAG (t @ s)) (Th th) \<and> th' \<in> running (t@s)" |
868 using th_blockedE assms by blast |
868 using th_blockedE assms by blast |
869 |
869 |
870 text {* |
870 text {* |
871 Now it is easy to see there is always a thread to run by case analysis |
871 Now it is easy to see there is always a thread to run by case analysis |
872 on whether thread @{term th} is running: if the answer is Yes, the |
872 on whether thread @{term th} is running: if the answer is Yes, the |
873 the running thread is obviously @{term th} itself; otherwise, the running |
873 the running thread is obviously @{term th} itself; otherwise, the running |
874 thread is the @{text th'} given by lemma @{thm th_blockedE}. |
874 thread is the @{text th'} given by lemma @{thm th_blockedE}. |
875 *} |
875 *} |
876 lemma live: "runing (t@s) \<noteq> {}" |
876 lemma live: "running (t@s) \<noteq> {}" |
877 proof(cases "th \<in> runing (t@s)") |
877 proof(cases "th \<in> running (t@s)") |
878 case True thus ?thesis by auto |
878 case True thus ?thesis by auto |
879 next |
879 next |
880 case False |
880 case False |
881 thus ?thesis using th_blockedE by auto |
881 thus ?thesis using th_blockedE by auto |
882 qed |
882 qed |
883 |
883 |
884 lemma blockedE: |
884 lemma blockedE: |
885 assumes "th \<notin> runing (t@s)" |
885 assumes "th \<notin> running (t@s)" |
886 obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
886 obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
887 "th' \<in> runing (t@s)" |
887 "th' \<in> running (t@s)" |
888 "th' \<in> threads s" |
888 "th' \<in> threads s" |
889 "\<not>detached s th'" |
889 "\<not>detached s th'" |
890 "cp (t@s) th' = preced th s" |
890 "cp (t@s) th' = preced th s" |
891 "th' \<noteq> th" |
891 "th' \<noteq> th" |
892 by (metis assms runing_inversion(2) runing_preced_inversion runing_threads_inv th_blockedE) |
892 by (metis assms running_inversion(2) running_preced_inversion running_threads_inv th_blockedE) |
893 |
893 |
894 lemma detached_not_runing: |
894 lemma detached_not_running: |
895 assumes "detached (t@s) th'" |
895 assumes "detached (t@s) th'" |
896 and "th' \<noteq> th" |
896 and "th' \<noteq> th" |
897 shows "th' \<notin> runing (t@s)" |
897 shows "th' \<notin> running (t@s)" |
898 proof |
898 proof |
899 assume otherwise: "th' \<in> runing (t @ s)" |
899 assume otherwise: "th' \<in> running (t @ s)" |
900 have "cp (t@s) th' = cp (t@s) th" |
900 have "cp (t@s) th' = cp (t@s) th" |
901 proof - |
901 proof - |
902 have "cp (t@s) th' = Max (cp (t@s) ` readys (t@s))" using otherwise |
902 have "cp (t@s) th' = Max (cp (t@s) ` readys (t@s))" using otherwise |
903 by (simp add:runing_def) |
903 by (simp add:running_def) |
904 moreover have "cp (t@s) th = ..." by (simp add: vat_t.max_cp_readys_threads) |
904 moreover have "cp (t@s) th = ..." by (simp add: vat_t.max_cp_readys_threads) |
905 ultimately show ?thesis by simp |
905 ultimately show ?thesis by simp |
906 qed |
906 qed |
907 moreover have "cp (t@s) th' = preced th' (t@s)" using assms(1) |
907 moreover have "cp (t@s) th' = preced th' (t@s)" using assms(1) |
908 by (simp add: detached_cp_preced) |
908 by (simp add: detached_cp_preced) |
909 moreover have "cp (t@s) th = preced th (t@s)" by simp |
909 moreover have "cp (t@s) th = preced th (t@s)" by simp |
910 ultimately have "preced th' (t@s) = preced th (t@s)" by simp |
910 ultimately have "preced th' (t@s) = preced th (t@s)" by simp |
911 from preced_unique[OF this] |
911 from preced_unique[OF this] |
912 have "th' \<in> threads (t @ s) \<Longrightarrow> th \<in> threads (t @ s) \<Longrightarrow> th' = th" . |
912 have "th' \<in> threads (t @ s) \<Longrightarrow> th \<in> threads (t @ s) \<Longrightarrow> th' = th" . |
913 moreover have "th' \<in> threads (t@s)" |
913 moreover have "th' \<in> threads (t@s)" |
914 using otherwise by (unfold runing_def readys_def, auto) |
914 using otherwise by (unfold running_def readys_def, auto) |
915 moreover have "th \<in> threads (t@s)" by (simp add: th_kept) |
915 moreover have "th \<in> threads (t@s)" by (simp add: th_kept) |
916 ultimately have "th' = th" by metis |
916 ultimately have "th' = th" by metis |
917 with assms(2) show False by simp |
917 with assms(2) show False by simp |
918 qed |
918 qed |
919 |
919 |
1122 qed |
1122 qed |
1123 next |
1123 next |
1124 case h1: (Cons e1 t1) |
1124 case h1: (Cons e1 t1) |
1125 hence eq_t': "t' = e1#t1" using h by simp |
1125 hence eq_t': "t' = e1#t1" using h by simp |
1126 from h(5)[OF h1] |
1126 from h(5)[OF h1] |
1127 have le: "length (actions_of {th} t) \<le> occs (\<lambda>t'. th \<in> runing (t' @ s)) t1" |
1127 have le: "length (actions_of {th} t) \<le> occs (\<lambda>t'. th \<in> running (t' @ s)) t1" |
1128 (is "?F t \<le> ?G t1") . |
1128 (is "?F t \<le> ?G t1") . |
1129 show ?thesis |
1129 show ?thesis |
1130 proof(cases "actor e = th") |
1130 proof(cases "actor e = th") |
1131 case True |
1131 case True |
1132 from ve'.th_no_create[OF _ this] |
1132 from ve'.th_no_create[OF _ this] |
1133 have "\<not> isCreate e" by auto |
1133 have "\<not> isCreate e" by auto |
1134 from PIP_actorE[OF h(2) True this] |
1134 from PIP_actorE[OF h(2) True this] |
1135 have "th \<in> runing (t@s)" by simp |
1135 have "th \<in> running (t@s)" by simp |
1136 hence "?R = 1 + ?G t1" by (unfold h1 eq_t', simp) |
1136 hence "?R = 1 + ?G t1" by (unfold h1 eq_t', simp) |
1137 moreover have "?L = 1 + ?F t" using True by (simp add:actions_of_def) |
1137 moreover have "?L = 1 + ?F t" using True by (simp add:actions_of_def) |
1138 ultimately show ?thesis using le by simp |
1138 ultimately show ?thesis using le by simp |
1139 next |
1139 next |
1140 case False |
1140 case False |
1271 the correctness of PIP. |
1271 the correctness of PIP. |
1272 |
1272 |
1273 *} |
1273 *} |
1274 |
1274 |
1275 theorem bound_priority_inversion: |
1275 theorem bound_priority_inversion: |
1276 "occs (\<lambda> t'. th \<notin> runing (t'@s)) t \<le> |
1276 "occs (\<lambda> t'. th \<notin> running (t'@s)) t \<le> |
1277 1 + (length (actions_of blockers t) + length (filter (isCreate) t))" |
1277 1 + (length (actions_of blockers t) + length (filter (isCreate) t))" |
1278 (is "?L \<le> ?R") |
1278 (is "?L \<le> ?R") |
1279 proof - |
1279 proof - |
1280 let ?Q = "(\<lambda> t'. th \<in> runing (t'@s))" |
1280 let ?Q = "(\<lambda> t'. th \<in> running (t'@s))" |
1281 from occs_le[of ?Q t] |
1281 from occs_le[of ?Q t] |
1282 have "?L \<le> (1 + length t) - occs ?Q t" by simp |
1282 have "?L \<le> (1 + length t) - occs ?Q t" by simp |
1283 also have "... \<le> ?R" |
1283 also have "... \<le> ?R" |
1284 proof - |
1284 proof - |
1285 have "length t - (length (actions_of blockers t) + length (filter (isCreate) t)) |
1285 have "length t - (length (actions_of blockers t) + length (filter (isCreate) t)) |
1286 \<le> occs (\<lambda> t'. th \<in> runing (t'@s)) t" (is "?L1 \<le> ?R1") |
1286 \<le> occs (\<lambda> t'. th \<in> running (t'@s)) t" (is "?L1 \<le> ?R1") |
1287 proof - |
1287 proof - |
1288 have "?L1 = length (actions_of {th} t)" using actions_split by arith |
1288 have "?L1 = length (actions_of {th} t)" using actions_split by arith |
1289 also have "... \<le> ?R1" using actions_th_occs by simp |
1289 also have "... \<le> ?R1" using actions_th_occs by simp |
1290 finally show ?thesis . |
1290 finally show ?thesis . |
1291 qed |
1291 qed |
1398 proof |
1398 proof |
1399 assume otherwise: "actor e = th'" |
1399 assume otherwise: "actor e = th'" |
1400 from ve'.blockers_no_create [OF assms _ this] |
1400 from ve'.blockers_no_create [OF assms _ this] |
1401 have "\<not> isCreate e" by auto |
1401 have "\<not> isCreate e" by auto |
1402 from PIP_actorE[OF h(2) otherwise this] |
1402 from PIP_actorE[OF h(2) otherwise this] |
1403 have "th' \<in> runing (t @ s)" . |
1403 have "th' \<in> running (t @ s)" . |
1404 moreover have "th' \<notin> runing (t @ s)" |
1404 moreover have "th' \<notin> running (t @ s)" |
1405 proof - |
1405 proof - |
1406 from False h(4) h(5) have "length (actions_of {th'} t) = span" by simp |
1406 from False h(4) h(5) have "length (actions_of {th'} t) = span" by simp |
1407 from fs[rule_format, OF h(3) this] have "detached (t @ s) th'" . |
1407 from fs[rule_format, OF h(3) this] have "detached (t @ s) th'" . |
1408 from extend_highest_gen.detached_not_runing[OF h(3) this] assms |
1408 from extend_highest_gen.detached_not_running[OF h(3) this] assms |
1409 show ?thesis by (auto simp:blockers_def) |
1409 show ?thesis by (auto simp:blockers_def) |
1410 qed |
1410 qed |
1411 ultimately show False by simp |
1411 ultimately show False by simp |
1412 qed |
1412 qed |
1413 with h show ?thesis by (auto simp:actions_of_def) |
1413 with h show ?thesis by (auto simp:actions_of_def) |