Correctness.thy
changeset 106 5454387e42ce
parent 104 43482ab31341
child 107 30ed212f268a
equal deleted inserted replaced
105:0c89419b4742 106:5454387e42ce
     1 theory Correctness
     1 theory Correctness
     2 imports PIPBasics
     2 imports PIPBasics
     3 begin
     3 begin
     4 
       
     5 lemma Setcompr_eq_image: "{f x | x. x \<in> A} = f ` A"
       
     6   by blast
       
     7 
     4 
     8 text {* 
     5 text {* 
     9   The following two auxiliary lemmas are used to reason about @{term Max}.
     6   The following two auxiliary lemmas are used to reason about @{term Max}.
    10 *}
     7 *}
    11 lemma image_Max_eqI: 
     8 lemma image_Max_eqI: 
   474     vat_s.le_cp)
   471     vat_s.le_cp)
   475 
   472 
   476 section {* The `blocking thread` *}
   473 section {* The `blocking thread` *}
   477 
   474 
   478 text {* 
   475 text {* 
   479 
   476   The purpose of PIP is to ensure that the most 
   480   The purpose of PIP is to ensure that the most urgent thread @{term
   477   urgent thread @{term th} is not blocked unreasonably. 
   481   th} is not blocked unreasonably. Therefore, below, we will derive
   478   Therefore, a clear picture of the blocking thread is essential 
   482   properties of the blocking thread. By blocking thread, we mean a
   479   to assure people that the purpose is fulfilled. 
   483   thread in running state t @ s, but is different from thread @{term
   480   
   484   th}.
   481   In this section, we are going to derive a series of lemmas 
   485 
   482   with finally give rise to a picture of the blocking thread. 
   486   The first lemmas shows that the @{term cp}-value of the blocking
   483 
   487   thread @{text th'} equals to the highest precedence in the whole
   484   By `blocking thread`, we mean a thread in running state but 
   488   system.
   485   different from thread @{term th}.
   489 
   486 *}
   490 *}
   487 
   491 
   488 text {*
       
   489   The following lemmas shows that the @{term cp}-value 
       
   490   of the blocking thread @{text th'} equals to the highest
       
   491   precedence in the whole system.
       
   492 *}
   492 lemma runing_preced_inversion:
   493 lemma runing_preced_inversion:
   493   assumes runing': "th' \<in> runing (t @ s)"
   494   assumes runing': "th' \<in> runing (t@s)"
   494   shows "cp (t @ s) th' = preced th s" 
   495   shows "cp (t@s) th' = preced th s" (is "?L = ?R")
   495 proof -
   496 proof -
   496   have "cp (t @ s) th' = Max (cp (t @ s) ` readys (t @ s))" 
   497   have "?L = Max (cp (t @ s) ` readys (t @ s))" using assms
   497     using assms by (unfold runing_def, auto)
   498       by (unfold runing_def, auto)
   498   also have "\<dots> = preced th s"
   499   also have "\<dots> = ?R"
   499     by (metis th_cp_max th_cp_preced vat_t.max_cp_readys_threads) 
   500       by (metis th_cp_max th_cp_preced vat_t.max_cp_readys_threads) 
   500   finally show ?thesis .
   501   finally show ?thesis .
   501 qed
   502 qed
   502 
   503 
   503 text {*
   504 text {*
   504 
   505 
   505   The next lemma shows how the counters for @{term "P"} and @{term
   506   The following lemma shows how the counters for @{term "P"} and
   506   "V"} operations relate to the running threads in the states @{term
   507   @{term "V"} operations relate to the running threads in the states
   507   s} and @{term "t @ s"}: if a thread's @{term "P"}-count equals its
   508   @{term s} and @{term "t @ s"}.  The lemma shows that if a thread's
   508   @{term "V"}-count (which means it no longer has any resource in its
   509   @{term "P"}-count equals its @{term "V"}-count (which means it no
   509   possession), it cannot be a running thread.
   510   longer has any resource in its possession), it cannot be a running
       
   511   thread.
   510 
   512 
   511   The proof is by contraction with the assumption @{text "th' \<noteq> th"}.
   513   The proof is by contraction with the assumption @{text "th' \<noteq> th"}.
   512   The key is the use of @{thm count_eq_dependants} to derive the
   514   The key is the use of @{thm eq_pv_dependants} to derive the
   513   emptiness of @{text th'}s @{term dependants}-set from the balance of
   515   emptiness of @{text th'}s @{term dependants}-set from the balance of
   514   its @{term P} and @{term V} counts.  From this, it can be shown
   516   its @{term P} and @{term V} counts.  From this, it can be shown
   515   @{text th'}s @{term cp}-value equals to its own precedence.
   517   @{text th'}s @{term cp}-value equals to its own precedence.
   516 
   518 
   517   On the other hand, since @{text th'} is running, by @{thm
   519   On the other hand, since @{text th'} is running, by @{thm
   518   runing_preced_inversion}, its @{term cp}-value equals to the
   520   runing_preced_inversion}, its @{term cp}-value equals to the
   519   precedence of @{term th}.
   521   precedence of @{term th}.
   520 
   522 
   521   Combining the above two results we have that @{text th'} and @{term
   523   Combining the above two resukts we have that @{text th'} and @{term
   522   th} have the same precedence. By uniqueness of precedences, we have
   524   th} have the same precedence. By uniqueness of precedences, we have
   523   @{text "th' = th"}, which is in contradiction with the assumption
   525   @{text "th' = th"}, which is in contradiction with the assumption
   524   @{text "th' \<noteq> th"}.
   526   @{text "th' \<noteq> th"}.
   525 
   527 
   526 *} 
   528 *} 
   527                       
   529                       
   528 lemma eq_pv_blocked: (* ddd *)
   530 lemma eq_pv_blocked: (* ddd *)
   529   assumes neq_th': "th' \<noteq> th"
   531   assumes neq_th': "th' \<noteq> th"
   530   and eq_pv: "cntP (t @ s) th' = cntV (t @ s) th'"
   532   and eq_pv: "cntP (t@s) th' = cntV (t@s) th'"
   531   shows "th' \<notin> runing (t @ s)"
   533   shows "th' \<notin> runing (t@s)"
   532 proof
   534 proof
   533   assume otherwise: "th' \<in> runing (t @ s)"
   535   assume otherwise: "th' \<in> runing (t@s)"
   534   show False
   536   show False
   535   proof -
   537   proof -
   536     have th'_in: "th' \<in> threads (t @ s)"
   538     have th'_in: "th' \<in> threads (t@s)"
   537         using otherwise readys_threads runing_def by auto 
   539         using otherwise readys_threads runing_def by auto 
   538     have "th' = th"
   540     have "th' = th"
   539     proof(rule preced_unique)
   541     proof(rule preced_unique)
   540       -- {* The proof goes like this: 
   542       -- {* The proof goes like this: 
   541             it is first shown that the @{term preced}-value of @{term th'} 
   543             it is first shown that the @{term preced}-value of @{term th'} 
   545       show "preced th' (t @ s) = preced th (t @ s)" (is "?L = ?R")
   547       show "preced th' (t @ s) = preced th (t @ s)" (is "?L = ?R")
   546       proof -
   548       proof -
   547         -- {* Since the counts of @{term th'} are balanced, the subtree
   549         -- {* Since the counts of @{term th'} are balanced, the subtree
   548               of it contains only itself, so, its @{term cp}-value
   550               of it contains only itself, so, its @{term cp}-value
   549               equals its @{term preced}-value: *}
   551               equals its @{term preced}-value: *}
   550         have "?L = cp (t @ s) th'"
   552         have "?L = cp (t@s) th'"
   551           by (unfold cp_eq_cpreced cpreced_def count_eq_dependants[OF eq_pv], simp)
   553          by (unfold cp_eq_cpreced cpreced_def eq_dependants vat_t.eq_pv_dependants[OF eq_pv], simp)
   552         -- {* Since @{term "th'"} is running, by @{thm runing_preced_inversion},
   554         -- {* Since @{term "th'"} is running, by @{thm runing_preced_inversion},
   553               its @{term cp}-value equals @{term "preced th s"}, 
   555               its @{term cp}-value equals @{term "preced th s"}, 
   554               which equals to @{term "?R"} by simplification: *}
   556               which equals to @{term "?R"} by simplification: *}
   555         also have "... = ?R" 
   557         also have "... = ?R" 
       
   558         thm runing_preced_inversion
   556             using runing_preced_inversion[OF otherwise] by simp
   559             using runing_preced_inversion[OF otherwise] by simp
   557         finally show ?thesis .
   560         finally show ?thesis .
   558       qed
   561       qed
   559     qed (auto simp: th'_in th_kept)
   562     qed (auto simp: th'_in th_kept)
   560     with `th' \<noteq> th` show ?thesis by simp
   563     with `th' \<noteq> th` show ?thesis by simp
   568   it will keep hand-emptied in the future @{term "t@s"}.
   571   it will keep hand-emptied in the future @{term "t@s"}.
   569 *}
   572 *}
   570 lemma eq_pv_persist: (* ddd *)
   573 lemma eq_pv_persist: (* ddd *)
   571   assumes neq_th': "th' \<noteq> th"
   574   assumes neq_th': "th' \<noteq> th"
   572   and eq_pv: "cntP s th' = cntV s th'"
   575   and eq_pv: "cntP s th' = cntV s th'"
   573   shows "cntP (t @ s) th' = cntV (t @ s) th'"
   576   shows "cntP (t@s) th' = cntV (t@s) th'"
   574 proof(induction rule: ind) 
   577 proof(induction rule:ind) -- {* The proof goes by induction. *}
   575   -- {* The nontrivial case is for the @{term Cons}: *}
   578   -- {* The nontrivial case is for the @{term Cons}: *}
   576   case (Cons e t)
   579   case (Cons e t)
   577   -- {* All results derived so far hold for both @{term s} and @{term "t@s"}: *}
   580   -- {* All results derived so far hold for both @{term s} and @{term "t@s"}: *}
   578   interpret vat_t: extend_highest_gen s th prio tm t using Cons by simp
   581   interpret vat_t: extend_highest_gen s th prio tm t using Cons by simp
   579   interpret vat_e: extend_highest_gen s th prio tm "(e # t)" using Cons by simp
   582   interpret vat_e: extend_highest_gen s th prio tm "(e # t)" using Cons by simp
   619     ultimately show ?thesis using Cons(5) by metis
   622     ultimately show ?thesis using Cons(5) by metis
   620   qed
   623   qed
   621 qed (auto simp:eq_pv)
   624 qed (auto simp:eq_pv)
   622 
   625 
   623 text {*
   626 text {*
   624 
   627   By combining @{thm  eq_pv_blocked} and @{thm eq_pv_persist},
   625   By combining @{thm eq_pv_blocked} and @{thm eq_pv_persist}, it can
   628   it can be derived easily that @{term th'} can not be running in the future:
   626   be derived easily that @{term th'} can not be running in the future:
   629 *}
   627 
       
   628 *}
       
   629 
       
   630 lemma eq_pv_blocked_persist:
   630 lemma eq_pv_blocked_persist:
   631   assumes neq_th': "th' \<noteq> th"
   631   assumes neq_th': "th' \<noteq> th"
   632   and eq_pv: "cntP s th' = cntV s th'"
   632   and eq_pv: "cntP s th' = cntV s th'"
   633   shows "th' \<notin> runing (t @ s)"
   633   shows "th' \<notin> runing (t@s)"
   634   using assms
   634   using assms
   635   by (simp add: eq_pv_blocked eq_pv_persist) 
   635   by (simp add: eq_pv_blocked eq_pv_persist) 
   636 
   636 
   637 text {*
   637 text {*
   638 
   638   The following lemma shows the blocking thread @{term th'}
   639   The following lemma shows the blocking thread @{term th'} must hold
   639   must hold some resource in the very beginning. 
   640   some resource in the very beginning.
   640 *}
   641 
       
   642 *}
       
   643 
       
   644 lemma runing_cntP_cntV_inv: (* ddd *)
   641 lemma runing_cntP_cntV_inv: (* ddd *)
   645   assumes is_runing: "th' \<in> runing (t @ s)"
   642   assumes is_runing: "th' \<in> runing (t@s)"
   646   and neq_th': "th' \<noteq> th"
   643   and neq_th': "th' \<noteq> th"
   647   shows "cntP s th' > cntV s th'"
   644   shows "cntP s th' > cntV s th'"
   648   using assms
   645   using assms
   649 proof -
   646 proof -
   650   -- {* First, it can be shown that the number of @{term P} and
   647   -- {* First, it can be shown that the number of @{term P} and
   666   ultimately show ?thesis by auto
   663   ultimately show ?thesis by auto
   667 qed
   664 qed
   668 
   665 
   669 
   666 
   670 text {*
   667 text {*
   671 
   668   The following lemmas shows the blocking thread @{text th'} must be live 
   672   The following lemmas shows the blocking thread @{text th'} must be
   669   at the very beginning, i.e. the moment (or state) @{term s}. 
   673   live at the very beginning, i.e. the moment (or state) @{term s}.
   670 
   674   The proof is a  simple combination of the results above:
   671   The proof is a  simple combination of the results above:
   675 
   672 *}
   676 *}
       
   677 
       
   678 lemma runing_threads_inv: 
   673 lemma runing_threads_inv: 
   679   assumes runing': "th' \<in> runing (t@s)"
   674   assumes runing': "th' \<in> runing (t@s)"
   680   and neq_th': "th' \<noteq> th"
   675   and neq_th': "th' \<noteq> th"
   681   shows "th' \<in> threads s"
   676   shows "th' \<in> threads s"
   682 proof(rule ccontr) -- {* Proof by contradiction: *}
   677 proof(rule ccontr) -- {* Proof by contradiction: *}
   690   qed
   685   qed
   691   with runing' show False by simp
   686   with runing' show False by simp
   692 qed
   687 qed
   693 
   688 
   694 text {*
   689 text {*
   695 
   690   The following lemma summarizes several foregoing 
   696   The following lemma summarises the above lemmas to give an overall
   691   lemmas to give an overall picture of the blocking thread @{text "th'"}:
   697   characterisationof the blocking thread @{text "th'"}:
   692 *}
   698 
       
   699 *}
       
   700 
       
   701 lemma runing_inversion: (* ddd, one of the main lemmas to present *)
   693 lemma runing_inversion: (* ddd, one of the main lemmas to present *)
   702   assumes runing': "th' \<in> runing (t@s)"
   694   assumes runing': "th' \<in> runing (t@s)"
   703   and neq_th: "th' \<noteq> th"
   695   and neq_th: "th' \<noteq> th"
   704   shows "th' \<in> threads s"
   696   shows "th' \<in> threads s"
   705   and    "\<not>detached s th'"
   697   and    "\<not>detached s th'"
   713 next
   705 next
   714   from runing_preced_inversion[OF runing']
   706   from runing_preced_inversion[OF runing']
   715   show "cp (t@s) th' = preced th s" .
   707   show "cp (t@s) th' = preced th s" .
   716 qed
   708 qed
   717 
   709 
   718 
       
   719 section {* The existence of `blocking thread` *}
   710 section {* The existence of `blocking thread` *}
   720 
   711 
   721 text {* 
   712 text {* 
   722 
   713   Suppose @{term th} is not running, it is first shown that
   723   Suppose @{term th} is not running, it is first shown that there is a
   714   there is a path in RAG leading from node @{term th} to another thread @{text "th'"} 
   724   path in RAG leading from node @{term th} to another thread @{text
   715   in the @{term readys}-set (So @{text "th'"} is an ancestor of @{term th}}).
   725   "th'"} in the @{term readys}-set (So @{text "th'"} is an ancestor of
   716 
   726   @{term th}}).
   717   Now, since @{term readys}-set is non-empty, there must be
   727 
   718   one in it which holds the highest @{term cp}-value, which, by definition, 
   728   Now, since @{term readys}-set is non-empty, there must be one in it
   719   is the @{term runing}-thread. However, we are going to show more: this running thread
   729   which holds the highest @{term cp}-value, which, by definition, is
   720   is exactly @{term "th'"}.
   730   the @{term runing}-thread. However, we are going to show more: this
   721      *}
   731   running thread is exactly @{term "th'"}.
       
   732 
       
   733 *}
       
   734 
       
   735 lemma th_blockedE: (* ddd, the other main lemma to be presented: *)
   722 lemma th_blockedE: (* ddd, the other main lemma to be presented: *)
   736   assumes "th \<notin> runing (t @ s)"
   723   assumes "th \<notin> runing (t@s)"
   737   obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)"
   724   obtains th' where "Th th' \<in> ancestors (RAG (t @ s)) (Th th)"
   738                     "th' \<in> runing (t @ s)"
   725                     "th' \<in> runing (t@s)"
   739 proof -
   726 proof -
   740   -- {* According to @{thm vat_t.th_chain_to_ready}, either 
   727   -- {* According to @{thm vat_t.th_chain_to_ready}, either 
   741         @{term "th"} is in @{term "readys"} or there is path leading from it to 
   728         @{term "th"} is in @{term "readys"} or there is path leading from it to 
   742         one thread in @{term "readys"}. *}
   729         one thread in @{term "readys"}. *}
   743   have "th \<in> readys (t @ s) \<or> (\<exists>th'. th' \<in> readys (t @ s) \<and> (Th th, Th th') \<in> (RAG (t @ s))\<^sup>+)" 
   730   have "th \<in> readys (t @ s) \<or> (\<exists>th'. th' \<in> readys (t @ s) \<and> (Th th, Th th') \<in> (RAG (t @ s))\<^sup>+)" 
   761       also have "... = (the_preced (t @ s) \<circ> the_thread) (Th th)"
   748       also have "... = (the_preced (t @ s) \<circ> the_thread) (Th th)"
   762       proof(rule image_Max_subset)
   749       proof(rule image_Max_subset)
   763         show "finite (Th ` (threads (t@s)))" by (simp add: vat_t.finite_threads)
   750         show "finite (Th ` (threads (t@s)))" by (simp add: vat_t.finite_threads)
   764       next
   751       next
   765         show "subtree (tRAG (t @ s)) (Th th') \<subseteq> Th ` threads (t @ s)"
   752         show "subtree (tRAG (t @ s)) (Th th') \<subseteq> Th ` threads (t @ s)"
   766           by (metis Range.intros dp trancl_range vat_t.range_in vat_t.subtree_tRAG_thread) 
   753           by (metis Range.intros dp trancl_range vat_t.rg_RAG_threads vat_t.subtree_tRAG_thread) 
   767       next
   754       next
   768         show "Th th \<in> subtree (tRAG (t @ s)) (Th th')" using dp
   755         show "Th th \<in> subtree (tRAG (t @ s)) (Th th')" using dp
   769                     by (unfold tRAG_subtree_eq, auto simp:subtree_def)
   756                     by (unfold tRAG_subtree_eq, auto simp:subtree_def)
   770       next
   757       next
   771         show "Max ((the_preced (t @ s) \<circ> the_thread) ` Th ` threads (t @ s)) =
   758         show "Max ((the_preced (t @ s) \<circ> the_thread) ` Th ` threads (t @ s)) =
   791     using `(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+` by (auto simp:ancestors_def)
   778     using `(Th th, Th th') \<in> (RAG (t @ s))\<^sup>+` by (auto simp:ancestors_def)
   792   ultimately show ?thesis using that by metis
   779   ultimately show ?thesis using that by metis
   793 qed
   780 qed
   794 
   781 
   795 text {*
   782 text {*
   796 
   783   Now it is easy to see there is always a thread to run by case analysis
   797   Now it is easy to see there is always a thread to run by case
   784   on whether thread @{term th} is running: if the answer is Yes, the 
   798   analysis on whether thread @{term th} is running: if the answer is
   785   the running thread is obviously @{term th} itself; otherwise, the running
   799   yes, the the running thread is obviously @{term th} itself;
   786   thread is the @{text th'} given by lemma @{thm th_blockedE}.
   800   otherwise, the running thread is the @{text th'} given by lemma
   787 *}
   801   @{thm th_blockedE}.
   788 lemma live: "runing (t@s) \<noteq> {}"
   802 
   789 proof(cases "th \<in> runing (t@s)") 
   803 *}
       
   804 
       
   805 lemma live: "runing (t @ s) \<noteq> {}"
       
   806 proof(cases "th \<in> runing (t @ s)") 
       
   807   case True thus ?thesis by auto
   790   case True thus ?thesis by auto
   808 next
   791 next
   809   case False
   792   case False
   810   thus ?thesis using th_blockedE by auto
   793   thus ?thesis using th_blockedE by auto
   811 qed
   794 qed
   812 
   795 
   813 
       
   814 end
   796 end
   815 end
   797 end