728 show "cp (t@s) th' = preced th s" . |
718 show "cp (t@s) th' = preced th s" . |
729 qed |
719 qed |
730 |
720 |
731 section {* The existence of `blocking thread` *} |
721 section {* The existence of `blocking thread` *} |
732 |
722 |
733 lemma th_ancestor_has_max_ready: |
723 text {* |
734 assumes th'_in: "th' \<in> readys (t@s)" |
724 Suppose @{term th} is not running, it is first shown that |
735 and dp: "th' \<in> nancestors (tG (t @ s)) th" |
725 there is a path in RAG leading from node @{term th} to another thread @{text "th'"} |
736 shows "cp (t @ s) th' = Max (cp (t @ s) ` readys (t @ s))" (is "?L = ?R") |
726 in the @{term readys}-set (So @{text "th'"} is an ancestor of @{term th}}). |
|
727 |
|
728 Now, since @{term readys}-set is non-empty, there must be |
|
729 one in it which holds the highest @{term cp}-value, which, by definition, |
|
730 is the @{term running}-thread. However, we are going to show more: this running thread |
|
731 is exactly @{term "th'"}. |
|
732 *} |
|
733 lemma th_blockedE: (* ddd, the other main lemma to be presented: *) |
|
734 assumes "th \<notin> running (t@s)" |
|
735 obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
|
736 "th' \<in> running (t@s)" |
737 proof - |
737 proof - |
|
738 -- {* According to @{thm vat_t.th_chain_to_ready}, either |
|
739 @{term "th"} is in @{term "readys"} or there is path leading from it to |
|
740 one thread in @{term "readys"}. *} |
|
741 have "th \<in> readys (t @ s) \<or> (\<exists>th'. th' \<in> readys (t @ s) \<and> (Th th, Th th') \<in> (RAG (t @ s))\<^sup>+)" |
|
742 using th_kept vat_t.th_chain_to_ready by auto |
|
743 -- {* However, @{term th} can not be in @{term readys}, because otherwise, since |
|
744 @{term th} holds the highest @{term cp}-value, it must be @{term "running"}. *} |
|
745 moreover have "th \<notin> readys (t@s)" |
|
746 using assms running_def th_cp_max vat_t.max_cp_readys_threads by auto |
|
747 -- {* So, there must be a path from @{term th} to another thread @{text "th'"} in |
|
748 term @{term readys}: *} |
|
749 ultimately obtain th' where th'_in: "th' \<in> readys (t@s)" |
|
750 and dp: "(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+" by auto |
|
751 -- {* We are going to show that this @{term th'} is running. *} |
|
752 have "th' \<in> running (t@s)" |
|
753 proof - |
|
754 -- {* We only need to show that this @{term th'} holds the highest @{term cp}-value: *} |
|
755 have "cp (t@s) th' = Max (cp (t@s) ` readys (t@s))" (is "?L = ?R") |
|
756 proof - |
738 -- {* First, by the alternative definition of @{term cp} (I mean @{thm cp_alt_def1}), |
757 -- {* First, by the alternative definition of @{term cp} (I mean @{thm cp_alt_def1}), |
739 the @{term cp}-value of @{term th'} is the maximum of |
758 the @{term cp}-value of @{term th'} is the maximum of |
740 all precedences of all thread nodes in its @{term tRAG}-subtree: *} |
759 all precedences of all thread nodes in its @{term tRAG}-subtree: *} |
741 have "?L = Max (the_preced (t @ s) ` (subtree (tG (t @ s)) th'))" |
760 have "?L = Max ((the_preced (t @ s) \<circ> the_thread) ` subtree (tRAG (t @ s)) (Th th'))" |
742 by (unfold cp_alt_def2, simp) |
761 by (unfold cp_alt_def1, simp) |
|
762 also have "... = (the_preced (t @ s) \<circ> the_thread) (Th th)" |
|
763 proof(rule image_Max_subset) |
|
764 show "finite (Th ` (threads (t@s)))" by (simp add: vat_t.finite_threads) |
|
765 next |
|
766 show "subtree (tRAG (t @ s)) (Th th') \<subseteq> Th ` threads (t @ s)" |
|
767 by (metis Range.intros dp trancl_range vat_t.rg_RAG_threads vat_t.subtree_tRAG_thread) |
|
768 next |
|
769 show "Th th \<in> subtree (tRAG (t @ s)) (Th th')" using dp |
|
770 by (unfold tRAG_subtree_eq, auto simp:subtree_def) |
|
771 next |
|
772 show "Max ((the_preced (t @ s) \<circ> the_thread) ` Th ` threads (t @ s)) = |
|
773 (the_preced (t @ s) \<circ> the_thread) (Th th)" (is "Max ?L = _") |
|
774 proof - |
|
775 have "?L = the_preced (t @ s) ` threads (t @ s)" |
|
776 by (unfold image_comp, rule image_cong, auto) |
|
777 thus ?thesis using max_preced the_preced_def by auto |
|
778 qed |
|
779 qed |
|
780 thm the_preced_def |
|
781 also have "... = ?R" |
|
782 using th_cp_max th_cp_preced th_kept |
|
783 the_preced_def vat_t.max_cp_readys_threads by auto |
|
784 thm th_cp_max th_cp_preced th_kept |
|
785 the_preced_def vat_t.max_cp_readys_threads |
|
786 finally show ?thesis . |
|
787 qed |
|
788 -- {* Now, since @{term th'} holds the highest @{term cp} |
|
789 and we have already show it is in @{term readys}, |
|
790 it is @{term running} by definition. *} |
|
791 with `th' \<in> readys (t@s)` show ?thesis by (simp add: running_def) |
|
792 qed |
|
793 -- {* It is easy to show @{term th'} is an ancestor of @{term th}: *} |
|
794 moreover have "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
|
795 using `(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+` by (auto simp:ancestors_def) |
|
796 ultimately show ?thesis using that by metis |
|
797 qed |
|
798 |
|
799 lemma (* new proof of th_blockedE *) |
|
800 assumes "th \<notin> running (t @ s)" |
|
801 obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
|
802 "th' \<in> running (t @ s)" |
|
803 proof - |
|
804 |
|
805 -- {* According to @{thm vat_t.th_chain_to_ready}, either @{term "th"} is |
|
806 in @{term "readys"} or there is path in the @{term RAG} leading from |
|
807 it to a thread that is in @{term "readys"}. However, @{term th} cannot |
|
808 be in @{term readys}, because otherwise, since @{term th} holds the |
|
809 highest @{term cp}-value, it must be @{term "running"}. This would |
|
810 violate our assumption. *} |
|
811 have "th \<notin> readys (t @ s)" |
|
812 using assms running_def th_cp_max vat_t.max_cp_readys_threads by auto |
|
813 then have "\<exists>th'. th' \<in> readys (t @ s) \<and> (Th th, Th th') \<in> (RAG (t @ s))\<^sup>+" |
|
814 using th_kept vat_t.th_chain_to_ready by auto |
|
815 then obtain th' where th'_in: "th' \<in> readys (t@s)" |
|
816 and dp: "(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+" by auto |
|
817 |
|
818 -- {* We are going to first show that this @{term th'} is running. *} |
|
819 have "th' \<in> running (t @ s)" |
|
820 proof - |
|
821 -- {* For this we need to show that @{term th'} holds the highest @{term cp}-value: *} |
|
822 have "cp (t @ s) th' = Max (cp (t @ s) ` readys (t @ s))" (is "?L = ?R") |
|
823 proof - |
|
824 -- {* First, by the alternative definition of @{term cp} (I mean @{thm cp_alt_def1}), |
|
825 the @{term cp}-value of @{term th'} is the maximum of |
|
826 all precedences of all thread nodes in its @{term tRAG}-subtree: *} |
|
827 have "?L = Max (the_preced (t @ s) ` (the_thread ` subtree (tRAG (t @ s)) (Th th')))" |
|
828 proof - |
|
829 have "(the_preced (t @ s) \<circ> the_thread) ` subtree (tRAG (t @ s)) (Th th') = |
|
830 the_preced (t @ s) ` the_thread ` subtree (tRAG (t @ s)) (Th th')" |
|
831 by fastforce |
|
832 thus ?thesis by (unfold cp_alt_def1, simp) |
|
833 qed |
743 also have "... = (the_preced (t @ s) th)" |
834 also have "... = (the_preced (t @ s) th)" |
744 proof(rule image_Max_subset) |
835 proof(rule image_Max_subset) |
745 show "finite (threads (t @ s))" by (simp add: vat_t.finite_threads) |
836 show "finite (threads (t @ s))" by (simp add: vat_t.finite_threads) |
746 next |
837 next |
747 show "subtree (tG (t @ s)) th' \<subseteq> threads (t @ s)" |
838 show "the_thread ` subtree (tRAG (t @ s)) (Th th') \<subseteq> threads (t @ s)" |
748 using readys_def th'_in vat_t.subtree_tG_thread by auto |
839 by (smt imageE mem_Collect_eq readys_def subsetCE subsetI th'_in |
|
840 the_thread.simps vat_t.subtree_tRAG_thread) |
749 next |
841 next |
750 show "th \<in> subtree (tG (t @ s)) th'" |
842 show "th \<in> the_thread ` subtree (tRAG (t @ s)) (Th th')" |
751 using dp unfolding subtree_def nancestors_def2 by simp |
843 proof - |
|
844 have "Th th \<in> subtree (tRAG (t @ s)) (Th th')" using dp |
|
845 by (unfold tRAG_subtree_eq, auto simp:subtree_def) |
|
846 thus ?thesis by force |
|
847 qed |
752 next |
848 next |
753 show " Max (the_preced (t @ s) ` threads (t @ s)) = the_preced (t @ s) th" |
849 show "Max (the_preced (t @ s) ` threads (t @ s)) = the_preced (t @ s) th" |
754 by simp |
850 by simp |
755 qed |
851 qed |
756 also have "... = ?R" |
852 also have "... = ?R" |
757 using th_cp_max th_cp_preced th_kept |
853 using th_cp_max th_cp_preced th_kept |
758 the_preced_def vat_t.max_cp_readys_threads by auto |
854 the_preced_def vat_t.max_cp_readys_threads by auto |
759 finally show "cp (t @ s) th' = Max (cp (t @ s) ` readys (t @ s))" . |
855 finally show "cp (t @ s) th' = Max (cp (t @ s) ` readys (t @ s))" . |
760 qed |
856 qed |
761 |
857 |
762 |
858 -- {* Now, since @{term th'} holds the highest @{term cp}-value in readys, |
763 text {* |
859 it is @{term running} by definition. *} |
764 Suppose @{term th} is not running, it is first shown that |
860 with `th' \<in> readys (t @ s)` show "th' \<in> running (t @ s)" by (simp add: running_def) |
765 there is a path in RAG leading from node @{term th} to another thread @{text "th'"} |
861 qed |
766 in the @{term readys}-set (So @{text "th'"} is an ancestor of @{term th}}). |
862 |
767 |
|
768 Now, since @{term readys}-set is non-empty, there must be |
|
769 one in it which holds the highest @{term cp}-value, which, by definition, |
|
770 is the @{term running}-thread. However, we are going to show more: this |
|
771 running thread is exactly @{term "th'"}. *} |
|
772 |
|
773 |
|
774 lemma th_blockedE: (* ddd, the other main lemma to be presented: *) |
|
775 obtains th' where "th' \<in> nancestors (tG (t @ s)) th" |
|
776 "th' \<in> running (t @ s)" |
|
777 proof - |
|
778 -- {* According to @{thm vat_t.th_chain_to_ready}, there is a |
|
779 ready ancestor of @{term th}. *} |
|
780 have "\<exists>th' \<in> nancestors (tG (t @ s)) th. th' \<in> readys (t @ s)" |
|
781 using th_kept vat_t.th_chain_to_ready_tG by auto |
|
782 then obtain th' where th'_in: "th' \<in> readys (t @ s)" |
|
783 and dp: "th' \<in> nancestors (tG (t @ s)) th" |
|
784 by blast |
|
785 |
|
786 -- {* We are going to first show that this @{term th'} is running. *} |
|
787 |
|
788 from th'_in dp |
|
789 have "cp (t @ s) th' = Max (cp (t @ s) ` readys (t @ s))" |
|
790 by (rule th_ancestor_has_max_ready) |
|
791 with `th' \<in> readys (t @ s)` |
|
792 have "th' \<in> running (t @ s)" by (simp add: running_def) |
|
793 |
|
794 -- {* It is easy to show @{term th'} is an ancestor of @{term th}: *} |
863 -- {* It is easy to show @{term th'} is an ancestor of @{term th}: *} |
795 moreover have "th' \<in> nancestors (tG (t @ s)) th" |
864 moreover have "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
796 using dp unfolding nancestors_def2 by simp |
865 using `(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+` by (auto simp:ancestors_def) |
797 ultimately show ?thesis using that by metis |
866 ultimately show ?thesis using that by metis |
798 qed |
867 qed |
799 |
868 |
800 lemma th_blockedE_pretty: |
869 lemma th_blockedE_pretty: |
801 shows "\<exists>th' \<in> nancestors (tG (t @ s)) th. th' \<in> running (t @ s)" |
870 assumes "th \<notin> running (t@s)" |
802 using th_blockedE assms |
871 shows "\<exists>th'. Th th' \<in> ancestors (RAG (t @ s)) (Th th) \<and> th' \<in> running (t@s)" |
803 by blast |
872 using th_blockedE assms by blast |
804 |
|
805 |
873 |
806 text {* |
874 text {* |
807 Now it is easy to see there is always a thread to run by case analysis |
875 Now it is easy to see there is always a thread to run by case analysis |
808 on whether thread @{term th} is running: if the answer is yes, the |
876 on whether thread @{term th} is running: if the answer is Yes, the |
809 the running thread is obviously @{term th} itself; otherwise, the running |
877 the running thread is obviously @{term th} itself; otherwise, the running |
810 thread is the @{text th'} given by lemma @{thm th_blockedE}. |
878 thread is the @{text th'} given by lemma @{thm th_blockedE}. |
811 *} |
879 *} |
812 lemma live: "running (t @ s) \<noteq> {}" |
880 lemma live: "running (t@s) \<noteq> {}" |
813 using th_blockedE by auto |
881 proof(cases "th \<in> running (t@s)") |
|
882 case True thus ?thesis by auto |
|
883 next |
|
884 case False |
|
885 thus ?thesis using th_blockedE by auto |
|
886 qed |
814 |
887 |
815 lemma blockedE: |
888 lemma blockedE: |
816 assumes "th \<notin> running (t @ s)" |
889 assumes "th \<notin> running (t@s)" |
817 obtains th' where "th' \<in> nancestors (tG (t @ s)) th" |
890 obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)" |
818 "th' \<in> running (t @ s)" |
891 "th' \<in> running (t@s)" |
819 "th' \<in> threads s" |
892 "th' \<in> threads s" |
820 "\<not>detached s th'" |
893 "\<not>detached s th'" |
821 "cp (t @ s) th' = preced th s" |
894 "cp (t@s) th' = preced th s" |
822 "th' \<noteq> th" |
895 "th' \<noteq> th" |
823 proof - |
896 by (metis assms running_inversion(2) running_preced_inversion running_threads_inv th_blockedE) |
824 obtain th' where a: "th' \<in> nancestors (tG (t @ s)) th" "th' \<in> running (t @ s)" |
|
825 using th_blockedE by blast |
|
826 moreover |
|
827 from a(2) have b: "th' \<in> threads s" |
|
828 using running_threads_inv assms by metis |
|
829 moreover |
|
830 from a(2) have "\<not>detached s th'" |
|
831 using running_inversion(2) assms by metis |
|
832 moreover |
|
833 from a(2) have "cp (t @ s) th' = preced th s" |
|
834 using running_preced_inversion by blast |
|
835 moreover |
|
836 from a(2) have "th' \<noteq> th" using assms a(2) by blast |
|
837 ultimately show ?thesis using that by metis |
|
838 qed |
|
839 |
|
840 |
|
841 lemma nblockedE: |
|
842 assumes "th \<notin> running (t @ s)" |
|
843 obtains th' where "th' \<in> ancestors (tG (t @ s)) th" |
|
844 "th' \<in> running (t @ s)" |
|
845 "th' \<in> threads s" |
|
846 "\<not>detached s th'" |
|
847 "cp (t @ s) th' = preced th s" |
|
848 "th' \<noteq> th" |
|
849 using blockedE unfolding nancestors_def |
|
850 using assms nancestors3 by auto |
|
851 |
|
852 |
897 |
853 lemma detached_not_running: |
898 lemma detached_not_running: |
854 assumes "detached (t @ s) th'" |
899 assumes "detached (t@s) th'" |
855 and "th' \<noteq> th" |
900 and "th' \<noteq> th" |
856 shows "th' \<notin> running (t @ s)" |
901 shows "th' \<notin> running (t@s)" |
857 proof |
902 proof |
858 assume otherwise: "th' \<in> running (t @ s)" |
903 assume otherwise: "th' \<in> running (t @ s)" |
859 have "cp (t@s) th' = cp (t@s) th" |
904 have "cp (t@s) th' = cp (t@s) th" |
860 proof - |
905 proof - |
861 have "cp (t@s) th' = Max (cp (t@s) ` readys (t@s))" using otherwise |
906 have "cp (t@s) th' = Max (cp (t@s) ` readys (t@s))" using otherwise |
1301 with False |
1323 with False |
1302 show ?thesis by auto |
1324 show ?thesis by auto |
1303 qed simp |
1325 qed simp |
1304 qed auto |
1326 qed auto |
1305 |
1327 |
1306 |
1328 context extend_highest_gen |
|
1329 begin |
|
1330 |
|
1331 |
|
1332 (* (* this lemma does not hold *) |
|
1333 lemma actions_th_occs': "length (actions_of {th} t) = occs' (\<lambda>t'. th \<in> running (t' @ s)) t" |
|
1334 sorry |
|
1335 *) |
|
1336 |
|
1337 |
|
1338 lemma actions_th_occs'_pre: |
|
1339 assumes "t = e'#t'" |
|
1340 shows "length (actions_of {th} t) \<le> occs' (\<lambda> t'. th \<in> running (t'@s)) t" |
|
1341 using assms |
|
1342 proof(induct arbitrary: e' t' rule:ind) |
|
1343 case h: (Cons e t e' t') |
|
1344 interpret vt: valid_trace "(t@s)" using h(1) |
|
1345 by (unfold_locales, simp) |
|
1346 interpret ve: extend_highest_gen s th prio tm t using h by simp |
|
1347 interpret ve': extend_highest_gen s th prio tm "e#t" using h by simp |
|
1348 show ?case (is "?L \<le> ?R") |
|
1349 proof(cases t) |
|
1350 case Nil |
|
1351 show ?thesis |
|
1352 proof(cases "actor e = th") |
|
1353 case True |
|
1354 from ve'.th_no_create[OF _ this] |
|
1355 have "\<not> isCreate e" by auto |
|
1356 from PIP_actorE[OF h(2) True this] Nil |
|
1357 have "th \<in> running s" by simp |
|
1358 hence "?R = 1" using Nil h by simp |
|
1359 moreover have "?L = 1" using True Nil by (simp add:actions_of_def) |
|
1360 ultimately show ?thesis by simp |
|
1361 next |
|
1362 case False |
|
1363 with Nil |
|
1364 show ?thesis by (auto simp:actions_of_def) |
|
1365 qed |
|
1366 next |
|
1367 case h1: (Cons e1 t1) |
|
1368 hence eq_t': "t' = e1#t1" using h by simp |
|
1369 from h(5)[OF h1] |
|
1370 have le: "length (actions_of {th} t) \<le> occs' (\<lambda>t'. th \<in> running (t' @ s)) t" |
|
1371 (is "?F t \<le> ?G t1") . |
|
1372 show ?thesis |
|
1373 proof(cases "actor e = th") |
|
1374 case True |
|
1375 from ve'.th_no_create[OF _ this] |
|
1376 have "\<not> isCreate e" by auto |
|
1377 from PIP_actorE[OF h(2) True this] |
|
1378 have "th \<in> running (t@s)" by simp |
|
1379 hence "?R = 1 + ?G t1" by (unfold h1 eq_t', simp) |
|
1380 moreover have "?L = 1 + ?F t" using True by (simp add:actions_of_def) |
|
1381 ultimately show ?thesis using le by simp |
|
1382 next |
|
1383 case False |
|
1384 with le |
|
1385 show ?thesis by (unfold h1 eq_t', simp add:actions_of_def) |
|
1386 qed |
|
1387 qed |
|
1388 qed auto |
|
1389 |
|
1390 text {* |
|
1391 The following lemma is a simple corollary of @{thm actions_th_occs_pre}. It is the |
|
1392 lemma really needed in later proofs. |
|
1393 *} |
|
1394 |
|
1395 |
|
1396 lemma occs'_replacement1: "occs' (\<lambda> t'. th \<in> running (t'@s)) t = length (filter (\<lambda> s'. th \<in> running s') (up_to s t))" |
|
1397 proof - |
|
1398 have h: "((\<lambda>s'. th \<in> running s') \<circ> (\<lambda>t'. t' @ s)) = (\<lambda> t'. th \<in> running (t' @ s))" by (rule ext, simp) |
|
1399 thus ?thesis |
|
1400 by (unfold occs'_def up_to_def length_filter_map h, simp) |
|
1401 qed |
|
1402 |
|
1403 lemma occs'_replacement2: "occs' (\<lambda> t'. th \<notin> running (t'@s)) t = length (filter (\<lambda> s'. th \<notin> running s') (up_to s t))" |
|
1404 proof - |
|
1405 have h: "((\<lambda>s'. th \<notin> running s') \<circ> (\<lambda>t'. t' @ s)) = (\<lambda> t'. th \<notin> running (t' @ s))" by (rule ext, simp) |
|
1406 thus ?thesis |
|
1407 by (unfold occs'_def up_to_def length_filter_map h, simp) |
|
1408 qed |
|
1409 |
|
1410 lemma actions_th_occs': |
|
1411 shows "length (actions_of {th} t) \<le> occs' (\<lambda> t'. th \<in> running (t'@s)) t" |
|
1412 proof(cases t) |
|
1413 case (Cons e' t') |
|
1414 from actions_th_occs'_pre[OF this] |
|
1415 have "length (actions_of {th} t) \<le> occs' (\<lambda>t'. th \<in> running (t' @ s)) t" . |
|
1416 thus ?thesis by simp |
|
1417 qed (auto simp:actions_of_def) |
|
1418 |
|
1419 theorem bound_priority_inversion': |
|
1420 "occs' (\<lambda> t'. th \<notin> running (t'@s)) t \<le> |
|
1421 (length (actions_of blockers t) + length (filter (isCreate) t))" |
|
1422 (is "?L \<le> ?R") |
|
1423 proof - |
|
1424 let ?Q = "(\<lambda> t'. th \<in> running (t'@s))" |
|
1425 from occs_len'[of ?Q t] |
|
1426 have "?L \<le> (length t) - occs' ?Q t" by simp |
|
1427 also have "... \<le> ?R" |
|
1428 proof - |
|
1429 have "length t - (length (actions_of blockers t) + length (filter (isCreate) t)) |
|
1430 \<le> occs' (\<lambda> t'. th \<in> running (t'@s)) t" (is "?L1 \<le> ?R1") |
|
1431 proof - |
|
1432 have "?L1 = length (actions_of {th} t)" using actions_split by arith |
|
1433 also have "... \<le> ?R1" using actions_th_occs' by simp |
|
1434 finally show ?thesis . |
|
1435 qed |
|
1436 thus ?thesis by simp |
|
1437 qed |
|
1438 finally show ?thesis . |
|
1439 qed |
|
1440 |
|
1441 theorem bound_priority_inversion: |
|
1442 "occs (\<lambda> t'. th \<notin> running (t'@s)) t \<le> |
|
1443 1 + (length (actions_of blockers t) + length (filter (isCreate) t))" |
|
1444 (is "?L \<le> ?R") |
|
1445 proof - |
|
1446 let ?Q = "(\<lambda> t'. th \<in> running (t'@s))" |
|
1447 from occs_le[of ?Q t] |
|
1448 have "?L \<le> 1 + (length t) - occs ?Q t" by simp |
|
1449 also have "... \<le> ?R" |
|
1450 proof - |
|
1451 have "length t - (length (actions_of blockers t) + length (filter (isCreate) t)) |
|
1452 \<le> occs (\<lambda> t'. th \<in> running (t'@s)) t" (is "?L1 \<le> ?R1") |
|
1453 proof - |
|
1454 have "?L1 = length (actions_of {th} t)" using actions_split by arith |
|
1455 also have "... \<le> ?R1" using actions_th_occs by simp |
|
1456 finally show ?thesis . |
|
1457 qed |
|
1458 thus ?thesis by simp |
|
1459 qed |
|
1460 finally show ?thesis . |
|
1461 qed |
|
1462 |
|
1463 end |
1307 |
1464 |
1308 text {* |
1465 text {* |
1309 As explained before, lemma @{text bound_priority_inversion} alone does not |
1466 As explained before, lemma @{text bound_priority_inversion} alone does not |
1310 ensure the correctness of PIP. For PIP to be correct, the number of blocking operations |
1467 ensure the correctness of PIP. For PIP to be correct, the number of blocking operations |
1311 (by {\em blocking operation}, we mean the @{term Create}-operations and |
1468 (by {\em blocking operation}, we mean the @{term Create}-operations and |
1318 -- {* |
1475 -- {* |
1319 To bound operations of blockers, the locale specifies that each blocker |
1476 To bound operations of blockers, the locale specifies that each blocker |
1320 releases all resources and becomes detached after a certain number |
1477 releases all resources and becomes detached after a certain number |
1321 of operations. In the assumption, this number is given by the |
1478 of operations. In the assumption, this number is given by the |
1322 existential variable @{text span}. Notice that this number is fixed for each |
1479 existential variable @{text span}. Notice that this number is fixed for each |
1323 blocker regardless of any particular instance of @{term t} in which it operates. |
1480 blocker regardless of any particular instance of @{term t'} in which it operates. |
1324 |
1481 |
1325 This assumption is reasonable, because it is a common sense that |
1482 This assumption is reasonable, because it is a common sense that |
1326 the total number of operations take by any standalone thread (or process) |
1483 the total number of operations take by any standalone thread (or process) |
1327 is only determined by its own input, and should not be affected by |
1484 is only determined by its own input, and should not be affected by |
1328 the particular environment in which it operates. In this particular case, |
1485 the particular environment in which it operates. In this particular case, |
1329 we regard the @{term t} as the environment of thread @{term th}. |
1486 we regard the @{term t} as the environment of thread @{term th}. |
1330 *} |
1487 *} |
1331 assumes finite_span: |
1488 (* |
|
1489 assumes finite_span: |
|
1490 "th' \<in> blockers \<Longrightarrow> |
|
1491 (\<exists> span. \<forall> t'. extend_highest_gen s th prio tm t' \<longrightarrow> |
|
1492 length (actions_of {th'} t') = span \<longrightarrow> detached (t'@s) th')" |
|
1493 *) |
|
1494 |
|
1495 -- {* |
|
1496 The above definition and explain is problematic because the number of actions taken |
|
1497 by @{term th'} may be affected by is environment not modeled by the events of our |
|
1498 PIP model. |
|
1499 *} |
|
1500 |
|
1501 -- {* |
|
1502 However, we still need to express the idea that every blocker becomes detached in bounded |
|
1503 number of steps. Supposing @{term span} is such a bound, the following @{term finite_span} |
|
1504 assumption says if @{term th'} is not @{term detached} in state (t'@s), then its number |
|
1505 of actions must be less than this bound @{term span}: |
|
1506 *} |
|
1507 |
|
1508 assumes finite_span: |
1332 "th' \<in> blockers \<Longrightarrow> |
1509 "th' \<in> blockers \<Longrightarrow> |
1333 (\<exists> span. \<forall> t'. extend_highest_gen s th prio tm t' \<longrightarrow> |
1510 (\<exists> span. \<forall> t'. extend_highest_gen s th prio tm t' \<longrightarrow> |
1334 \<not> detached (t'@s) th' \<longrightarrow> length (actions_of {th'} t') < span)" |
1511 \<not> detached (t'@s) th' \<longrightarrow> length (actions_of {th'} t') < span)" |
1335 |
1512 |
1336 -- {* |
1513 -- {* |
1337 The difference between this @{text finite_span} and the former one is to allow the number |
1514 The difference between this @{text finite_span} and the former one is to allow the number |
1338 of action steps to change with execution paths (i.e. different value of @{term "t'@s"}}). |
1515 of action steps to change with execution paths (i.e. different value of @{term "t'@s"}}). |
1339 The @{term span} is a upper bound on these step numbers. |
1516 The @{term span} is a upper bound on these step numbers. |
1340 *} |
1517 *} |
1341 |
1518 |
|
1519 -- {* The following @{text BC} is bound of @{term Create}-operations *} |
1342 fixes BC |
1520 fixes BC |
1343 -- {* |
1521 -- {* |
1344 The following assumption requires the number of @{term Create}-operations is |
1522 The following assumption requires the number of @{term Create}-operations is |
1345 less or equal to @{term BC} regardless of any particular extension of @{term t}. |
1523 less or equal to @{term BC} regardless of any particular extension of @{term t}. |
1346 |
1524 |