|     49       thus "distinct q" by auto |     49       thus "distinct q" by auto | 
|     50     qed |     50     qed | 
|     51   qed |     51   qed | 
|     52 qed |     52 qed | 
|     53  |     53  | 
|     54 lemma step_back_vt: "vt (e#s) \<Longrightarrow> vt s" |     54 text {* | 
|     55   by(ind_cases "vt (e#s)", simp) |     55   The following lemma shows that only the @{text "P"} | 
|     56  |     56   operation can add new thread into waiting queues.  | 
|     57 lemma step_back_step: "vt (e#s) \<Longrightarrow> step s e" |     57   Such kind of lemmas are very obvious, but need to be checked formally. | 
|     58   by(ind_cases "vt (e#s)", simp) |     58   This is a kind of confirmation that our modelling is correct. | 
|         |     59 *} | 
|     59  |     60  | 
|     60 lemma block_pre:  |     61 lemma block_pre:  | 
|     61   fixes thread cs s |     62   fixes thread cs s | 
|     62   assumes vt_e: "vt (e#s)" |     63   assumes vt_e: "vt (e#s)" | 
|     63   and s_ni: "thread \<notin>  set (wq s cs)" |     64   and s_ni: "thread \<notin>  set (wq s cs)" | 
|    108       qed |    109       qed | 
|    109       ultimately show "False" by auto |    110       ultimately show "False" by auto | 
|    110       qed |    111       qed | 
|    111   qed |    112   qed | 
|    112 qed |    113 qed | 
|         |    114  | 
|         |    115 text {* | 
|         |    116   The following lemmas is also obvious and shallow. It says | 
|         |    117   that only running thread can request for a critical resource  | 
|         |    118   and that the requested resource must be one which is | 
|         |    119   not current held by the thread. | 
|         |    120 *} | 
|    113  |    121  | 
|    114 lemma p_pre: "\<lbrakk>vt ((P thread cs)#s)\<rbrakk> \<Longrightarrow>  |    122 lemma p_pre: "\<lbrakk>vt ((P thread cs)#s)\<rbrakk> \<Longrightarrow>  | 
|    115   thread \<in> runing s \<and> (Cs cs, Th thread)  \<notin> (RAG s)^+" |    123   thread \<in> runing s \<and> (Cs cs, Th thread)  \<notin> (RAG s)^+" | 
|    116 apply (ind_cases "vt ((P thread cs)#s)") |    124 apply (ind_cases "vt ((P thread cs)#s)") | 
|    117 apply (ind_cases "step s (P thread cs)") |    125 apply (ind_cases "step s (P thread cs)") | 
|    199 qed |    207 qed | 
|    200  |    208  | 
|    201 (* Wrong: |    209 (* Wrong: | 
|    202     lemma \<lbrakk>thread \<in> set (wq_fun cs1 s); thread \<in> set (wq_fun cs2 s)\<rbrakk> \<Longrightarrow> cs1 = cs2" |    210     lemma \<lbrakk>thread \<in> set (wq_fun cs1 s); thread \<in> set (wq_fun cs2 s)\<rbrakk> \<Longrightarrow> cs1 = cs2" | 
|    203 *) |    211 *) | 
|         |    212  | 
|         |    213 text {* (* ??? *) | 
|         |    214   The nature of the work is like this: since it starts from a very simple and basic  | 
|         |    215   model, even intuitively very `basic` and `obvious` properties need to derived from scratch. | 
|         |    216   For instance, the fact  | 
|         |    217   that one thread can not be blocked by two critical resources at the same time | 
|         |    218   is obvious, because only running threads can make new requests, if one is waiting for  | 
|         |    219   a critical resource and get blocked, it can not make another resource request and get  | 
|         |    220   blocked the second time (because it is not running).  | 
|         |    221  | 
|         |    222   To derive this fact, one needs to prove by contraction and  | 
|         |    223   reason about time (or @{text "moement"}). The reasoning is based on a generic theorem | 
|         |    224   named @{text "p_split"}, which is about status changing along the time axis. It says if  | 
|         |    225   a condition @{text "Q"} is @{text "True"} at a state @{text "s"}, | 
|         |    226   but it was @{text "False"} at the very beginning, then there must exits a moment @{text "t"}  | 
|         |    227   in the history of @{text "s"} (notice that @{text "s"} itself is essentially the history  | 
|         |    228   of events leading to it), such that @{text "Q"} switched  | 
|         |    229   from being @{text "False"} to @{text "True"} and kept being @{text "True"} | 
|         |    230   till the last moment of @{text "s"}. | 
|         |    231  | 
|         |    232   Suppose a thread @{text "th"} is blocked | 
|         |    233   on @{text "cs1"} and @{text "cs2"} in some state @{text "s"},  | 
|         |    234   since no thread is blocked at the very beginning, by applying  | 
|         |    235   @{text "p_split"} to these two blocking facts, there exist  | 
|         |    236   two moments @{text "t1"} and @{text "t2"}  in @{text "s"}, such that  | 
|         |    237   @{text "th"} got blocked on @{text "cs1"} and @{text "cs2"}  | 
|         |    238   and kept on blocked on them respectively ever since. | 
|         |    239   | 
|         |    240   Without lose of generality, we assume @{text "t1"} is earlier than @{text "t2"}. | 
|         |    241   However, since @{text "th"} was blocked ever since memonent @{text "t1"}, so it was still | 
|         |    242   in blocked state at moment @{text "t2"} and could not | 
|         |    243   make any request and get blocked the second time: Contradiction. | 
|         |    244 *} | 
|    204  |    245  | 
|    205 lemma waiting_unique_pre: |    246 lemma waiting_unique_pre: | 
|    206   fixes cs1 cs2 s thread |    247   fixes cs1 cs2 s thread | 
|    207   assumes vt: "vt s" |    248   assumes vt: "vt s" | 
|    208   and h11: "thread \<in> set (wq s cs1)" |    249   and h11: "thread \<in> set (wq s cs1)" | 
|    405   from preced_unique [OF _ th_in1 th_in2] and neq_12  |    456   from preced_unique [OF _ th_in1 th_in2] and neq_12  | 
|    406   have "preced th1 s \<noteq> preced th2 s" by auto |    457   have "preced th1 s \<noteq> preced th2 s" by auto | 
|    407   thus ?thesis by auto |    458   thus ?thesis by auto | 
|    408 qed |    459 qed | 
|    409  |    460  | 
|         |    461 (* An aux lemma used later *) | 
|    410 lemma unique_minus: |    462 lemma unique_minus: | 
|    411   fixes x y z r |    463   fixes x y z r | 
|    412   assumes unique: "\<And> a b c. \<lbrakk>(a, b) \<in> r; (a, c) \<in> r\<rbrakk> \<Longrightarrow> b = c" |    464   assumes unique: "\<And> a b c. \<lbrakk>(a, b) \<in> r; (a, c) \<in> r\<rbrakk> \<Longrightarrow> b = c" | 
|    413   and xy: "(x, y) \<in> r" |    465   and xy: "(x, y) \<in> r" | 
|    414   and xz: "(x, z) \<in> r^+" |    466   and xz: "(x, z) \<in> r^+" | 
|    512 lemma RAG_exit_unchanged: "(RAG (Exit th # s)) = RAG s" |    570 lemma RAG_exit_unchanged: "(RAG (Exit th # s)) = RAG s" | 
|    513 apply (unfold s_RAG_def s_waiting_def wq_def) |    571 apply (unfold s_RAG_def s_waiting_def wq_def) | 
|    514 by (simp add:Let_def) |    572 by (simp add:Let_def) | 
|    515  |    573  | 
|    516  |    574  | 
|    517  |    575 text {*  | 
|         |    576   The following lemmas are used in the proof of  | 
|         |    577   lemma @{text "step_RAG_v"}, which characterizes how the @{text "RAG"} is changed | 
|         |    578   by @{text "V"}-events.  | 
|         |    579   However, since our model is very concise, such  seemingly obvious lemmas need to be derived from scratch, | 
|         |    580   starting from the model definitions. | 
|         |    581 *} | 
|    518 lemma step_v_hold_inv[elim_format]: |    582 lemma step_v_hold_inv[elim_format]: | 
|    519   "\<And>c t. \<lbrakk>vt (V th cs # s);  |    583   "\<And>c t. \<lbrakk>vt (V th cs # s);  | 
|    520   \<not> holding (wq s) t c; holding (wq (V th cs # s)) t c\<rbrakk> \<Longrightarrow> next_th s th cs t \<and> c = cs" |    584           \<not> holding (wq s) t c; holding (wq (V th cs # s)) t c\<rbrakk> \<Longrightarrow>  | 
|         |    585             next_th s th cs t \<and> c = cs" | 
|    521 proof - |    586 proof - | 
|    522   fix c t |    587   fix c t | 
|    523   assume vt: "vt (V th cs # s)" |    588   assume vt: "vt (V th cs # s)" | 
|    524     and nhd: "\<not> holding (wq s) t c" |    589     and nhd: "\<not> holding (wq s) t c" | 
|    525     and hd: "holding (wq (V th cs # s)) t c" |    590     and hd: "holding (wq (V th cs # s)) t c" | 
|    562     qed |    627     qed | 
|    563     with True show ?thesis by auto |    628     with True show ?thesis by auto | 
|    564   qed |    629   qed | 
|    565 qed |    630 qed | 
|    566  |    631  | 
|         |    632 text {*  | 
|         |    633   The following @{text "step_v_wait_inv"} is also an obvious lemma, which, however, needs to be | 
|         |    634   derived from scratch, which confirms the correctness of the definition of @{text "next_th"}. | 
|         |    635 *} | 
|    567 lemma step_v_wait_inv[elim_format]: |    636 lemma step_v_wait_inv[elim_format]: | 
|    568     "\<And>t c. \<lbrakk>vt (V th cs # s); \<not> waiting (wq (V th cs # s)) t c; waiting (wq s) t c |    637     "\<And>t c. \<lbrakk>vt (V th cs # s); \<not> waiting (wq (V th cs # s)) t c; waiting (wq s) t c | 
|    569            \<rbrakk> |    638            \<rbrakk> | 
|    570           \<Longrightarrow> (next_th s th cs t \<and> cs = c)" |    639           \<Longrightarrow> (next_th s th cs t \<and> cs = c)" | 
|    571 proof - |    640 proof - | 
|    788               step_v_release step_v_wait_inv |    861               step_v_release step_v_wait_inv | 
|    789               step_v_get_hold step_v_release_inv) |    862               step_v_get_hold step_v_release_inv) | 
|    790   apply (erule_tac step_v_not_wait, auto) |    863   apply (erule_tac step_v_not_wait, auto) | 
|    791   done |    864   done | 
|    792  |    865  | 
|         |    866 text {*  | 
|         |    867   The following @{text "step_RAG_p"} lemma charaterizes how @{text "RAG"} is changed | 
|         |    868   with the happening of @{text "P"}-events: | 
|         |    869 *} | 
|    793 lemma step_RAG_p: |    870 lemma step_RAG_p: | 
|    794   "vt (P th cs#s) \<Longrightarrow> |    871   "vt (P th cs#s) \<Longrightarrow> | 
|    795   RAG (P th cs # s) =  (if (wq s cs = []) then RAG s \<union> {(Cs cs, Th th)} |    872   RAG (P th cs # s) =  (if (wq s cs = []) then RAG s \<union> {(Cs cs, Th th)} | 
|    796                                              else RAG s \<union> {(Th th, Cs cs)})" |    873                                              else RAG s \<union> {(Th th, Cs cs)})" | 
|    797   apply(simp only: s_RAG_def wq_def) |    874   apply(simp only: s_RAG_def wq_def) | 
|    806  |    883  | 
|    807  |    884  | 
|    808 lemma RAG_target_th: "(Th th, x) \<in> RAG (s::state) \<Longrightarrow> \<exists> cs. x = Cs cs" |    885 lemma RAG_target_th: "(Th th, x) \<in> RAG (s::state) \<Longrightarrow> \<exists> cs. x = Cs cs" | 
|    809   by (unfold s_RAG_def, auto) |    886   by (unfold s_RAG_def, auto) | 
|    810  |    887  | 
|         |    888 text {* | 
|         |    889   The following lemma shows that @{text "RAG"} is acyclic. | 
|         |    890   The overall structure is by induction on the formation of @{text "vt s"} | 
|         |    891   and then case analysis on event @{text "e"}, where the non-trivial cases  | 
|         |    892   for those for @{text "V"} and @{text "P"} events. | 
|         |    893 *} | 
|    811 lemma acyclic_RAG:  |    894 lemma acyclic_RAG:  | 
|    812   fixes s |    895   fixes s | 
|    813   assumes vt: "vt s" |    896   assumes vt: "vt s" | 
|    814   shows "acyclic (RAG s)" |    897   shows "acyclic (RAG s)" | 
|    815 using assms |    898 using assms | 
|   1216       qed |   1299       qed | 
|   1217       with th_nin th_in show False by auto |   1300       with th_nin th_in show False by auto | 
|   1218     qed |   1301     qed | 
|   1219 qed |   1302 qed | 
|   1220  |   1303  | 
|         |   1304 text {* \noindent | 
|         |   1305   The following lemmas shows that: starting from any node in @{text "RAG"},  | 
|         |   1306   by chasing out-going edges, it is always possible to reach a node representing a ready | 
|         |   1307   thread. In this lemma, it is the @{text "th'"}. | 
|         |   1308 *} | 
|         |   1309  | 
|   1221 lemma chain_building: |   1310 lemma chain_building: | 
|   1222   assumes vt: "vt s" |   1311   assumes vt: "vt s" | 
|   1223   shows "node \<in> Domain (RAG s) \<longrightarrow> (\<exists> th'. th' \<in> readys s \<and> (node, Th th') \<in> (RAG s)^+)" |   1312   shows "node \<in> Domain (RAG s) \<longrightarrow> (\<exists> th'. th' \<in> readys s \<and> (node, Th th') \<in> (RAG s)^+)" | 
|   1224 proof - |   1313 proof - | 
|   1225   from wf_dep_converse [OF vt] |   1314   from wf_dep_converse [OF vt] | 
|   2358 lemma cnp_cnv_eq: |   2453 lemma cnp_cnv_eq: | 
|   2359   fixes th s |   2454   fixes th s | 
|   2360   assumes "vt s" |   2455   assumes "vt s" | 
|   2361   and "th \<notin> threads s" |   2456   and "th \<notin> threads s" | 
|   2362   shows "cntP s th = cntV s th" |   2457   shows "cntP s th = cntV s th" | 
|   2363 proof - |   2458  by (simp add: assms(1) assms(2) cnp_cnv_cncs not_thread_cncs) | 
|   2364   from assms show ?thesis |         | 
|   2365   proof(induct) |         | 
|   2366     case (vt_cons s e) |         | 
|   2367     have ih: "th \<notin> threads s \<Longrightarrow> cntP s th = cntV s th" by fact |         | 
|   2368     have not_in: "th \<notin> threads (e # s)" by fact |         | 
|   2369     have "step s e" by fact |         | 
|   2370     thus ?case proof(cases) |         | 
|   2371       case (thread_create thread prio) |         | 
|   2372       assume eq_e: "e = Create thread prio" |         | 
|   2373       hence "thread \<in> threads (e#s)" by simp |         | 
|   2374       with not_in and eq_e have "th \<notin> threads s" by auto |         | 
|   2375       from ih [OF this] show ?thesis using eq_e |         | 
|   2376         by (auto simp:cntP_def cntV_def count_def) |         | 
|   2377     next |         | 
|   2378       case (thread_exit thread) |         | 
|   2379       assume eq_e: "e = Exit thread" |         | 
|   2380         and not_holding: "holdents s thread = {}" |         | 
|   2381       have vt_s: "vt s" by fact |         | 
|   2382       from finite_holding[OF vt_s] have "finite (holdents s thread)" . |         | 
|   2383       with not_holding have "cntCS s thread = 0" by (unfold cntCS_def, auto) |         | 
|   2384       moreover have "thread \<in> readys s" using thread_exit by (auto simp:runing_def) |         | 
|   2385       moreover note cnp_cnv_cncs[OF vt_s, of thread] |         | 
|   2386       ultimately have eq_thread: "cntP s thread = cntV s thread" by auto |         | 
|   2387       show ?thesis |         | 
|   2388       proof(cases "th = thread") |         | 
|   2389         case True |         | 
|   2390         with eq_thread eq_e show ?thesis  |         | 
|   2391           by (auto simp:cntP_def cntV_def count_def) |         | 
|   2392       next |         | 
|   2393         case False |         | 
|   2394         with not_in and eq_e have "th \<notin> threads s" by simp |         | 
|   2395         from ih[OF this] and eq_e show ?thesis  |         | 
|   2396            by (auto simp:cntP_def cntV_def count_def) |         | 
|   2397       qed |         | 
|   2398     next |         | 
|   2399       case (thread_P thread cs) |         | 
|   2400       assume eq_e: "e = P thread cs" |         | 
|   2401       have "thread \<in> runing s" by fact |         | 
|   2402       with not_in eq_e have neq_th: "thread \<noteq> th"  |         | 
|   2403         by (auto simp:runing_def readys_def) |         | 
|   2404       from not_in eq_e have "th \<notin> threads s" by simp |         | 
|   2405       from ih[OF this] and neq_th and eq_e show ?thesis |         | 
|   2406         by (auto simp:cntP_def cntV_def count_def) |         | 
|   2407     next |         | 
|   2408       case (thread_V thread cs) |         | 
|   2409       assume eq_e: "e = V thread cs" |         | 
|   2410       have "thread \<in> runing s" by fact |         | 
|   2411       with not_in eq_e have neq_th: "thread \<noteq> th"  |         | 
|   2412         by (auto simp:runing_def readys_def) |         | 
|   2413       from not_in eq_e have "th \<notin> threads s" by simp |         | 
|   2414       from ih[OF this] and neq_th and eq_e show ?thesis |         | 
|   2415         by (auto simp:cntP_def cntV_def count_def) |         | 
|   2416     next |         | 
|   2417       case (thread_set thread prio) |         | 
|   2418       assume eq_e: "e = Set thread prio" |         | 
|   2419         and "thread \<in> runing s" |         | 
|   2420       hence "thread \<in> threads (e#s)"  |         | 
|   2421         by (simp add:runing_def readys_def) |         | 
|   2422       with not_in and eq_e have "th \<notin> threads s" by auto |         | 
|   2423       from ih [OF this] show ?thesis using eq_e |         | 
|   2424         by (auto simp:cntP_def cntV_def count_def)   |         | 
|   2425     qed |         | 
|   2426   next |         | 
|   2427     case vt_nil |         | 
|   2428     show ?case by (auto simp:cntP_def cntV_def count_def) |         | 
|   2429   qed |         | 
|   2430 qed |         | 
|   2431  |   2459  | 
|   2432 lemma eq_RAG:  |   2460 lemma eq_RAG:  | 
|   2433   "RAG (wq s) = RAG s" |   2461   "RAG (wq s) = RAG s" | 
|   2434 by (unfold cs_RAG_def s_RAG_def, auto) |   2462 by (unfold cs_RAG_def s_RAG_def, auto) | 
|   2435  |   2463  |