Attic/Test.thy
changeset 194 b32b3bd99150
parent 127 38c6acf03f68
equal deleted inserted replaced
193:c3a42076b164 194:b32b3bd99150
       
     1 theory Test 
       
     2 imports Precedence_ord Graphs
       
     3 begin
       
     4 
       
     5 type_synonym thread = nat -- {* Type for thread identifiers. *}
       
     6 type_synonym priority = nat  -- {* Type for priorities. *}
       
     7 type_synonym cs = nat -- {* Type for critical sections (or resources). *}
       
     8 
       
     9 -- {* Schedulling Events *}
       
    10 
       
    11 datatype event = 
       
    12   Create thread priority 
       
    13 | Exit thread 
       
    14 | P thread cs 
       
    15 | V thread cs 
       
    16 | Set thread priority 
       
    17 
       
    18 type_synonym state = "event list"
       
    19 
       
    20 fun threads :: "state \<Rightarrow> thread set"
       
    21   where 
       
    22   "threads [] = {}" 
       
    23 | "threads (Create th prio#s) = {th} \<union> threads s" 
       
    24 | "threads (Exit th # s) = (threads s) - {th}" 
       
    25 | "threads (_#s) = threads s" 
       
    26 
       
    27 fun priority :: "thread \<Rightarrow> state \<Rightarrow> priority"
       
    28   where
       
    29   "priority th [] = 0" 
       
    30 | "priority th (Create th' prio#s) = (if th' = th then prio else priority th s)" 
       
    31 | "priority th (Set th' prio#s) = (if th' = th then prio else priority th s)" 
       
    32 | "priority th (_#s) = priority th s"
       
    33 
       
    34 fun last_set :: "thread \<Rightarrow> state \<Rightarrow> nat"
       
    35   where
       
    36   "last_set th [] = 0" 
       
    37 | "last_set th ((Create th' prio)#s) = (if (th = th') then length s else last_set th s)" 
       
    38 | "last_set th ((Set th' prio)#s) = (if (th = th') then length s else last_set th s)" 
       
    39 | "last_set th (_#s) = last_set th s"
       
    40 
       
    41 
       
    42 definition preced :: "thread \<Rightarrow> state \<Rightarrow> precedence"
       
    43   where "preced th s \<equiv> Prc (priority th s) (last_set th s)"
       
    44 
       
    45 abbreviation 
       
    46   "preceds s ths \<equiv> {preced th s | th. th \<in> ths}"
       
    47  
       
    48 definition
       
    49   "holds wq th cs \<equiv> th \<in> set (wq cs) \<and> th = hd (wq cs)"
       
    50 
       
    51 definition
       
    52   "waits wq th cs \<equiv> th \<in> set (wq cs) \<and> th \<noteq> hd (wq cs)"
       
    53 
       
    54 --{* Nodes in Resource Graph *}
       
    55 datatype node = 
       
    56   Th "thread" 
       
    57 | Cs "cs" 
       
    58 
       
    59 definition
       
    60   "RAG wq \<equiv> {(Th th, Cs cs) | th cs. waits wq th cs} \<union> {(Cs cs, Th th) | cs th. holds wq th cs}"
       
    61 
       
    62 definition
       
    63   "dependants wq th \<equiv> {th' . (Th th', Th th) \<in> (RAG wq)^+}"
       
    64 
       
    65 record schedule_state = 
       
    66   wq_fun :: "cs \<Rightarrow> thread list" 
       
    67   cprec_fun :: "thread \<Rightarrow> precedence" 
       
    68 
       
    69 definition cpreced :: "(cs \<Rightarrow> thread list) \<Rightarrow> state \<Rightarrow> thread \<Rightarrow> precedence"
       
    70   where 
       
    71   "cpreced wq s th \<equiv> Max ({preced th s} \<union> {preced th' s | th'. th' \<in> dependants wq th})"
       
    72 
       
    73 abbreviation
       
    74   "all_unlocked \<equiv> \<lambda>_::cs. ([]::thread list)"
       
    75 
       
    76 abbreviation 
       
    77   "initial_cprec \<equiv> \<lambda>_::thread. Prc 0 0"
       
    78  
       
    79 abbreviation
       
    80   "release qs \<equiv> case qs of
       
    81              [] => [] 
       
    82           |  (_ # qs) => SOME q. distinct q \<and> set q = set qs"
       
    83 
       
    84 lemma [simp]: 
       
    85   "(SOME q. distinct q \<and> q = []) = []"
       
    86 by auto
       
    87 
       
    88 lemma [simp]: 
       
    89   "(x \<in> set (SOME q. distinct q \<and> set q = set p)) = (x \<in> set p)"
       
    90 apply(rule iffI)
       
    91 apply (metis (mono_tags, lifting) List.finite_set finite_distinct_list some_eq_ex)+
       
    92 done
       
    93 
       
    94 abbreviation
       
    95   "next_to_run ths \<equiv> hd (SOME q::thread list. distinct q \<and> set q = set ths)"
       
    96 
       
    97 
       
    98 fun schs :: "state \<Rightarrow> schedule_state"
       
    99   where 
       
   100   "schs [] = (| wq_fun = \<lambda> cs. [],  cprec_fun = (\<lambda>_. Prc 0 0) |)" 
       
   101 | "schs (Create th prio # s) = 
       
   102        (let wq = wq_fun (schs s) in
       
   103           (|wq_fun = wq, cprec_fun = cpreced wq (Create th prio # s)|))"
       
   104 |  "schs (Exit th # s) = 
       
   105        (let wq = wq_fun (schs s) in
       
   106           (|wq_fun = wq, cprec_fun = cpreced wq (Exit th # s)|))"
       
   107 |  "schs (Set th prio # s) = 
       
   108        (let wq = wq_fun (schs s) in
       
   109           (|wq_fun = wq, cprec_fun = cpreced wq (Set th prio # s)|))"
       
   110 |  "schs (P th cs # s) = 
       
   111        (let wq = wq_fun (schs s) in
       
   112         let new_wq = wq(cs := (wq cs @ [th])) in
       
   113           (|wq_fun = new_wq, cprec_fun = cpreced new_wq (P th cs # s)|))"
       
   114 |  "schs (V th cs # s) = 
       
   115        (let wq = wq_fun (schs s) in
       
   116         let new_wq = wq(cs := release (wq cs)) in
       
   117           (|wq_fun = new_wq, cprec_fun = cpreced new_wq (V th cs # s)|))"
       
   118 
       
   119 definition wq :: "state \<Rightarrow> cs \<Rightarrow> thread list" 
       
   120   where "wq s = wq_fun (schs s)"
       
   121 
       
   122 definition cpreced2 :: "state \<Rightarrow> thread \<Rightarrow> precedence"
       
   123   where "cpreced2 s \<equiv> cprec_fun (schs s)"
       
   124 
       
   125 abbreviation
       
   126   "cpreceds2 s ths \<equiv> {cpreced2 s th | th. th \<in> ths}"
       
   127 
       
   128 definition
       
   129   "holds2 s \<equiv> holds (wq_fun (schs s))"
       
   130 
       
   131 definition
       
   132   "waits2 s \<equiv> waits (wq_fun (schs s))"
       
   133 
       
   134 definition
       
   135   "RAG2 s \<equiv> RAG (wq_fun (schs s))"
       
   136   
       
   137 definition
       
   138   "dependants2 s \<equiv> dependants (wq_fun (schs s))"
       
   139 
       
   140 (* ready -> is a thread that is not waiting for any resource *) 
       
   141 definition readys :: "state \<Rightarrow> thread set"
       
   142   where "readys s \<equiv> {th . th \<in> threads s \<and> (\<forall> cs. \<not> waits2 s th cs)}"
       
   143 
       
   144 definition runing :: "state \<Rightarrow> thread set"
       
   145   where "runing s \<equiv> {th . th \<in> readys s \<and> cpreced2 s th = Max (cpreceds2 s (readys s))}"
       
   146 
       
   147 (* all resources a thread hols in a state *)
       
   148 definition holding :: "state \<Rightarrow> thread \<Rightarrow> cs set"
       
   149   where "holding s th \<equiv> {cs . holds2 s th cs}"
       
   150 
       
   151 
       
   152 lemma exists_distinct:
       
   153   obtains ys where "distinct ys" "set ys = set xs"
       
   154 by (metis List.finite_set finite_distinct_list)
       
   155 
       
   156 lemma next_to_run_set [simp]:
       
   157   "wts \<noteq> [] \<Longrightarrow> next_to_run wts \<in> set wts"
       
   158 apply(rule exists_distinct[of wts])
       
   159 by (metis (mono_tags, lifting) hd_in_set set_empty some_eq_ex)
       
   160 
       
   161 lemma holding_RAG: 
       
   162   "holding s th = {cs . (Cs cs, Th th) \<in> RAG2 s}"
       
   163 unfolding holding_def RAG2_def RAG_def
       
   164 unfolding holds2_def holds_def waits_def
       
   165 by auto
       
   166 
       
   167 inductive step :: "state \<Rightarrow> event \<Rightarrow> bool"
       
   168   where
       
   169   step_Create: "\<lbrakk>th \<notin> threads s\<rbrakk> \<Longrightarrow> step s (Create th prio)" 
       
   170 | step_Exit: "\<lbrakk>th \<in> runing s; holding s th = {}\<rbrakk> \<Longrightarrow> step s (Exit th)" 
       
   171 | step_P: "\<lbrakk>th \<in> runing s;  (Cs cs, Th th)  \<notin> (RAG2 s)^+\<rbrakk> \<Longrightarrow> step s (P th cs)" 
       
   172 | step_V: "\<lbrakk>th \<in> runing s;  holds2 s th cs\<rbrakk> \<Longrightarrow> step s (V th cs)" 
       
   173 | step_Set: "\<lbrakk>th \<in> runing s\<rbrakk> \<Longrightarrow> step s (Set th prio)"
       
   174 
       
   175 (* valid states *)
       
   176 inductive vt :: "state \<Rightarrow> bool"
       
   177   where
       
   178   vt_nil[intro]: "vt []" 
       
   179 | vt_cons[intro]: "\<lbrakk>vt s; step s e\<rbrakk> \<Longrightarrow> vt (e#s)"
       
   180 
       
   181 lemma runing_ready: 
       
   182   shows "runing s \<subseteq> readys s"
       
   183   unfolding runing_def readys_def
       
   184   by auto 
       
   185 
       
   186 lemma readys_threads:
       
   187   shows "readys s \<subseteq> threads s"
       
   188   unfolding readys_def
       
   189   by auto
       
   190 
       
   191 lemma wq_threads: 
       
   192   assumes vt: "vt s"
       
   193   and h: "th \<in> set (wq s cs)"
       
   194   shows "th \<in> threads s"
       
   195 using assms
       
   196 apply(induct)
       
   197 apply(simp add: wq_def)
       
   198 apply(erule step.cases)
       
   199 apply(auto simp add: wq_def Let_def holding_def holds2_def holds_def waits2_def runing_def readys_def)
       
   200 apply(simp add: waits_def)
       
   201 apply(auto simp add: waits_def split: if_splits)[1]
       
   202 apply(auto split: if_splits)
       
   203 apply(simp only: waits_def)
       
   204 by (metis insert_iff set_simps(2))
       
   205 
       
   206 
       
   207 
       
   208 lemma Domain_RAG_threads:
       
   209   assumes vt: "vt s"
       
   210   and in_dom: "(Th th) \<in> Domain (RAG2 s)"
       
   211   shows "th \<in> threads s"
       
   212 proof -
       
   213   from in_dom obtain n where "(Th th, n) \<in> RAG2 s" by auto
       
   214   then obtain cs where "n = Cs cs" "(Th th, Cs cs) \<in> RAG2 s"  
       
   215     unfolding RAG2_def RAG_def by auto
       
   216   then have "th \<in> set (wq s cs)"
       
   217     unfolding wq_def RAG_def RAG2_def waits_def by auto
       
   218   with wq_threads [OF vt] show ?thesis .
       
   219 qed
       
   220 
       
   221 lemma dependants_threads:
       
   222   assumes vt: "vt s"
       
   223   shows "dependants2 s th \<subseteq> threads s"
       
   224 proof
       
   225   fix th1 
       
   226   assume "th1 \<in> dependants2 s th"
       
   227   then have h: "(Th th1, Th th) \<in> (RAG2 s)\<^sup>+"
       
   228     unfolding dependants2_def dependants_def RAG2_def by simp
       
   229   then have "Th th1 \<in> Domain ((RAG2 s)\<^sup>+)" unfolding Domain_def by auto
       
   230   then have "Th th1 \<in> Domain (RAG2 s)" using trancl_domain by simp
       
   231   then show "th1 \<in> threads s" using vt by (rule_tac Domain_RAG_threads)
       
   232 qed
       
   233 
       
   234 lemma finite_threads:
       
   235   assumes vt: "vt s"
       
   236   shows "finite (threads s)"
       
   237 using vt by (induct) (auto elim: step.cases)
       
   238 
       
   239 
       
   240 section {* Distinctness of @{const wq} *}
       
   241 
       
   242 lemma wq_distinct_step: 
       
   243   assumes "step s e" "distinct (wq s cs)" 
       
   244   shows "distinct (wq (e # s) cs)"
       
   245 using assms
       
   246 unfolding wq_def
       
   247 apply(erule_tac step.cases)
       
   248 apply(auto simp add: RAG2_def RAG_def Let_def)[1]
       
   249 apply(auto simp add: wq_def Let_def RAG2_def RAG_def holds_def runing_def waits2_def waits_def readys_def)
       
   250 apply(auto split: list.split)
       
   251 apply(rule someI2)
       
   252 apply(auto)
       
   253 done
       
   254 
       
   255 lemma wq_distinct: 
       
   256   assumes "vt s" 
       
   257   shows "distinct (wq s cs)"
       
   258 using assms
       
   259 apply(induct)
       
   260 apply(simp add: wq_def)
       
   261 apply(simp add: wq_distinct_step)
       
   262 done
       
   263 
       
   264 
       
   265 section {* Single_Valuedness of @{const waits2}, @{const holds2}, @{const RAG2} *}
       
   266 
       
   267 lemma waits2_unique:
       
   268   assumes "vt s"
       
   269   and "waits2 s th cs1"
       
   270   and "waits2 s th cs2"
       
   271   shows "cs1 = cs2"
       
   272 using assms
       
   273 apply(induct)
       
   274 apply(simp add: waits2_def waits_def)
       
   275 apply(erule step.cases)
       
   276 apply(auto simp add: Let_def waits2_def waits_def holds_def RAG2_def RAG_def 
       
   277  readys_def runing_def split: if_splits)
       
   278 apply (metis Nil_is_append_conv hd_append2 list.distinct(1) split_list)
       
   279 apply (metis Nil_is_append_conv hd_append2 list.distinct(1) split_list)
       
   280 apply (metis distinct.simps(2) distinct_length_2_or_more list.sel(1) wq_def wq_distinct)
       
   281 by (metis (full_types, hide_lams) distinct.simps(2) distinct_length_2_or_more list.sel(1) wq_def wq_distinct)
       
   282 
       
   283 lemma single_valued_waits2:
       
   284   assumes "vt s"
       
   285   shows "single_valuedP (waits2 s)"
       
   286 using assms
       
   287 unfolding single_valued_def
       
   288 by (simp add: Product_Type.Collect_case_prodD waits2_unique)
       
   289 
       
   290 lemma single_valued_holds2:
       
   291   assumes "vt s"
       
   292   shows "single_valuedP (\<lambda>cs th. holds2 s th cs)"
       
   293 unfolding single_valued_def holds2_def holds_def by simp
       
   294 
       
   295 lemma single_valued_RAG2:
       
   296   assumes "vt s"
       
   297   shows "single_valued (RAG2 s)"
       
   298 using single_valued_waits2[OF assms] single_valued_holds2[OF assms] 
       
   299 unfolding RAG2_def RAG_def
       
   300 apply(rule_tac single_valued_union)
       
   301 unfolding holds2_def[symmetric] waits2_def[symmetric]
       
   302 apply(rule single_valued_Collect)
       
   303 apply(simp)
       
   304 apply(simp add: inj_on_def)
       
   305 apply(rule single_valued_Collect)
       
   306 apply(simp)
       
   307 apply(simp add: inj_on_def)
       
   308 apply(auto)
       
   309 done
       
   310 
       
   311 
       
   312 section {* Properties of @{const RAG2} under events *}
       
   313 
       
   314 lemma RAG_Set [simp]: 
       
   315   shows "RAG2 (Set th prio # s) = RAG2 s"
       
   316 unfolding RAG2_def
       
   317 by (simp add: Let_def)
       
   318 
       
   319 lemma RAG_Create [simp]: 
       
   320   "RAG2 (Create th prio # s) = RAG2 s"
       
   321 unfolding RAG2_def
       
   322 by (simp add: Let_def)
       
   323 
       
   324 lemma RAG_Exit [simp]: 
       
   325   shows "RAG2 (Exit th # s) = RAG2 s"
       
   326 unfolding RAG2_def
       
   327 by (simp add: Let_def)
       
   328 
       
   329 lemma RAG_P1:
       
   330   assumes "wq s cs = []"
       
   331   shows "RAG2 (P th cs # s) \<subseteq> RAG2 s \<union> {(Cs cs, Th th)}"
       
   332 using assms
       
   333 unfolding  RAG2_def RAG_def wq_def Let_def waits_def holds_def
       
   334 by (auto simp add: Let_def)
       
   335 
       
   336 lemma RAG_P2:
       
   337   assumes "(Cs cs, Th th) \<notin> (RAG2 s)\<^sup>+" "wq s cs \<noteq> []"
       
   338   shows "RAG2 (P th cs # s) \<subseteq> RAG2 s \<union> {(Th th, Cs cs)}"
       
   339 using assms
       
   340 unfolding RAG2_def RAG_def wq_def Let_def waits_def holds_def
       
   341 by (auto simp add: Let_def)
       
   342 
       
   343 
       
   344 lemma RAG_V1:
       
   345 assumes vt: "wq s cs = [th]"
       
   346 shows "RAG2 (V th cs # s) \<subseteq> RAG2 s - {(Cs cs, Th th)}"
       
   347 using assms
       
   348 unfolding RAG2_def RAG_def waits_def holds_def wq_def
       
   349 by (auto simp add: Let_def)
       
   350 
       
   351 lemma RAG_V2:
       
   352 assumes vt:"vt s" "wq s cs = th # wts \<and> wts \<noteq> []"
       
   353 shows "RAG2 (V th cs # s) \<subseteq>
       
   354   RAG2 s - {(Cs cs, Th th), (Th (next_to_run wts), Cs cs)} \<union> {(Cs cs, Th (next_to_run wts))}"
       
   355 unfolding RAG2_def RAG_def waits_def holds_def
       
   356 using assms wq_distinct[OF vt(1), of"cs"]
       
   357 by (auto simp add: Let_def wq_def)
       
   358 
       
   359 
       
   360 
       
   361 section {* Acyclicity of @{const RAG2} *}
       
   362 
       
   363 lemma acyclic_RAG_step: 
       
   364   assumes vt: "vt s"
       
   365   and     stp: "step s e"
       
   366   and     ac: "acyclic (RAG2 s)"
       
   367   shows "acyclic (RAG2 (e # s))"
       
   368 using stp vt ac
       
   369 proof (induct)
       
   370   case (step_P th s cs)
       
   371   have ac: "acyclic (RAG2 s)" by fact
       
   372   have ds: "(Cs cs, Th th) \<notin> (RAG2 s)\<^sup>+" by fact
       
   373   { assume wq_empty: "wq s cs = []" -- "case waiting queue is empty"
       
   374     then have "(Th th, Cs cs) \<notin> (RAG2 s)\<^sup>+"
       
   375     proof (rule_tac notI)
       
   376       assume "(Th th, Cs cs) \<in> (RAG2 s)\<^sup>+"
       
   377       then obtain x where "(x, Cs cs) \<in> RAG2 s" using tranclD2 by metis 
       
   378       with wq_empty show False by (auto simp: RAG2_def RAG_def wq_def waits_def)
       
   379     qed
       
   380     with ac have "acyclic (RAG2 s \<union> {(Cs cs, Th th)})" by simp
       
   381     then have "acyclic (RAG2 (P th cs # s))" using RAG_P1[OF wq_empty] 
       
   382       by (rule acyclic_subset)
       
   383   }
       
   384   moreover
       
   385   { assume wq_not_empty: "wq s cs \<noteq> []" -- "case waiting queue is not empty"
       
   386     from ac ds
       
   387     have "acyclic (RAG2 s \<union> {(Th th, Cs cs)})" by simp
       
   388     then have "acyclic (RAG2 (P th cs # s))" using RAG_P2[OF ds wq_not_empty] 
       
   389       by (rule acyclic_subset)
       
   390   }
       
   391   ultimately show "acyclic (RAG2 (P th cs # s))" by metis
       
   392 next    
       
   393   case (step_V th s cs) -- "case for release of a lock" 
       
   394   have vt: "vt s" by fact
       
   395   have ac: "acyclic (RAG2 s)" by fact
       
   396   have hd: "holds2 s th cs" by fact
       
   397   from vt have wq_distinct:"distinct (wq s cs)" by (rule wq_distinct)
       
   398   from hd have "th \<in> set (wq s cs)" "th = hd (wq s cs)" unfolding holds2_def holds_def wq_def by auto
       
   399   then obtain wts where eq_wq: "wq s cs = th # wts"  by (cases "wq s cs") (auto)
       
   400   -- "case no thread present in the waiting queue to take over"
       
   401   { assume "wts = []" 
       
   402     with eq_wq have "wq s cs = [th]" by simp
       
   403     then have "RAG2 (V th cs # s) \<subseteq> RAG2 s - {(Cs cs, Th th)}" by (rule RAG_V1)
       
   404     moreover have "acyclic (RAG2 s - {(Cs cs, Th th)})" using ac by (auto intro: acyclic_subset)
       
   405     ultimately 
       
   406     have "acyclic (RAG2 (V th cs # s))" by (auto intro: acyclic_subset)
       
   407   }
       
   408   moreover
       
   409   -- "at least one thread present to take over"
       
   410   { def nth \<equiv> "next_to_run wts"
       
   411     assume wq_not_empty: "wts \<noteq> []" 
       
   412     have "waits2 s nth cs" 
       
   413       using eq_wq wq_not_empty wq_distinct
       
   414       unfolding nth_def waits2_def waits_def wq_def[symmetric] by auto
       
   415     then have cs_in_RAG: "(Th nth, Cs cs) \<in> RAG2 s" 
       
   416       unfolding RAG2_def RAG_def waits2_def by auto
       
   417     have "RAG2 (V th cs # s) \<subseteq> RAG2 s - {(Cs cs, Th th), (Th nth, Cs cs)} \<union> {(Cs cs, Th nth)}" 
       
   418       unfolding nth_def using  vt wq_not_empty eq_wq by (rule_tac RAG_V2) (auto)
       
   419     moreover 
       
   420     have "acyclic (RAG2 s - {(Cs cs, Th th), (Th nth, Cs cs)} \<union> {(Cs cs, Th nth)})" 
       
   421     proof -
       
   422       have "acyclic (RAG2 s - {(Cs cs, Th th), (Th nth, Cs cs)})" using ac by (auto intro: acyclic_subset)
       
   423       moreover 
       
   424       have "(Th nth, Cs cs) \<notin> (RAG2 s - {(Cs cs, Th th), (Th nth, Cs cs)})\<^sup>+" 
       
   425       proof (rule notI)
       
   426         assume "(Th nth, Cs cs) \<in> (RAG2 s - {(Cs cs, Th th), (Th nth, Cs cs)})\<^sup>+"
       
   427         then obtain z where a: "(Th nth, z) \<in> (RAG2 s - {(Cs cs, Th th), (Th nth, Cs cs)})"
       
   428           by (metis converse_tranclE)
       
   429         then have "(Th nth, z) \<in> RAG2 s" by simp
       
   430         then have "z = Cs cs" using cs_in_RAG single_valued_RAG2[OF vt]
       
   431           by (simp add: single_valued_def)
       
   432         then show "False" using a by simp
       
   433       qed
       
   434       ultimately 
       
   435       show "acyclic (RAG2 s - {(Cs cs, Th th), (Th nth, Cs cs)} \<union> {(Cs cs, Th nth) })" by simp
       
   436     qed
       
   437     ultimately have "acyclic (RAG2 (V th cs # s))" 
       
   438       by (rule_tac acyclic_subset)
       
   439   }
       
   440   ultimately show "acyclic (RAG2 (V th cs # s))" by metis
       
   441 qed (simp_all)
       
   442 
       
   443 
       
   444 lemma finite_RAG:
       
   445   assumes "vt s"
       
   446   shows "finite (RAG2 s)"
       
   447 using assms
       
   448 apply(induct)
       
   449 apply(simp add: RAG2_def RAG_def waits_def holds_def)
       
   450 apply(erule step.cases)
       
   451 apply(auto)
       
   452 apply(case_tac "wq sa cs = []")
       
   453 apply(rule finite_subset)
       
   454 apply(rule RAG_P1)
       
   455 apply(simp)
       
   456 apply(simp)
       
   457 apply(rule finite_subset)
       
   458 apply(rule RAG_P2)
       
   459 apply(simp)
       
   460 apply(simp)
       
   461 apply(simp)
       
   462 apply(subgoal_tac "\<exists>wts. wq sa cs = th # wts")
       
   463 apply(erule exE)
       
   464 apply(case_tac "wts = []")
       
   465 apply(rule finite_subset)
       
   466 apply(rule RAG_V1)
       
   467 apply(simp)
       
   468 apply(simp)
       
   469 apply(rule finite_subset)
       
   470 apply(rule RAG_V2)
       
   471 apply(simp)
       
   472 apply(simp)
       
   473 apply(simp)
       
   474 apply(subgoal_tac "th \<in> set (wq sa cs) \<and> th = hd (wq sa cs)") 
       
   475 apply(case_tac "wq sa cs") 
       
   476 apply(auto)[2]
       
   477 apply(auto simp add: holds2_def holds_def wq_def)
       
   478 done
       
   479 
       
   480 
       
   481 
       
   482 lemma dchain_unique:
       
   483   assumes vt: "vt s"
       
   484   and th1_d: "(n, Th th1) \<in> (RAG2 s)^+"
       
   485   and th1_r: "th1 \<in> readys s"
       
   486   and th2_d: "(n, Th th2) \<in> (RAG2 s)^+"
       
   487   and th2_r: "th2 \<in> readys s"
       
   488   shows "th1 = th2"
       
   489 proof(rule ccontr)
       
   490   assume neq: "th1 \<noteq> th2"
       
   491    with single_valued_confluent2 [OF single_valued_RAG2 [OF vt]] th1_d th2_d
       
   492   have "(Th th1, Th th2) \<in> (RAG2 s)\<^sup>+ \<or> (Th th2, Th th1) \<in> (RAG2 s)\<^sup>+" by auto
       
   493   moreover
       
   494   { assume "(Th th1, Th th2) \<in> (RAG2 s)\<^sup>+"      
       
   495     then obtain n where dd: "(Th th1, n) \<in> RAG2 s" by (metis converse_tranclE)
       
   496     then obtain cs where eq_n: "n = Cs cs"
       
   497       unfolding RAG2_def RAG_def by (case_tac n) (auto)
       
   498     from dd eq_n have "th1 \<notin> readys s"
       
   499       unfolding RAG2_def RAG_def waits2_def readys_def by (auto)
       
   500     with th1_r have "False" by auto
       
   501   }
       
   502   moreover
       
   503   { assume "(Th th2, Th th1) \<in> (RAG2 s)\<^sup>+"
       
   504     then obtain n where dd: "(Th th2, n) \<in> RAG2 s" by (metis converse_tranclE)
       
   505     then obtain cs where eq_n: "n = Cs cs"
       
   506       unfolding RAG2_def RAG_def by (case_tac n) (auto)
       
   507     from dd eq_n have "th2 \<notin> readys s"
       
   508       unfolding RAG2_def RAG_def waits2_def readys_def by (auto)
       
   509     with th2_r have "False" by auto
       
   510   }
       
   511   ultimately show "False" by metis
       
   512 qed
       
   513 
       
   514 lemma cpreced2_cpreced: "cpreced2 s th = cpreced (wq s) s th"
       
   515 unfolding cpreced2_def wq_def
       
   516 apply(induct s rule: schs.induct)
       
   517 apply(simp add: Let_def cpreced_def dependants_def RAG_def waits_def holds_def preced_def)
       
   518 apply(simp add: Let_def)
       
   519 apply(simp add: Let_def)
       
   520 apply(simp add: Let_def)
       
   521 apply(subst (2) schs.simps)
       
   522 apply(simp add: Let_def)
       
   523 apply(subst (2) schs.simps)
       
   524 apply(simp add: Let_def)
       
   525 done
       
   526 
       
   527 lemma cpreced_Exit:
       
   528   shows "cpreced2 (Exit th # s) th' = cpreced2 s th'"
       
   529 by (simp add: cpreced2_cpreced cpreced_def preced_def wq_def Let_def)
       
   530 
       
   531 lemma readys_Exit:
       
   532   shows "readys (Exit th # s) = readys s - {th}"
       
   533 by (auto simp add: readys_def waits2_def Let_def)
       
   534 
       
   535 lemma readys_Create:
       
   536   shows "readys (Create th prio # s) \<subseteq> {th} \<union> readys s"
       
   537 apply (auto simp add: readys_def waits2_def Let_def waits_def)
       
   538 done
       
   539 
       
   540 lemma readys_Set:
       
   541   shows "readys (Set th prio # s) = readys s"
       
   542 by (auto simp add: readys_def waits2_def Let_def)
       
   543 
       
   544 
       
   545 lemma readys_P:
       
   546   shows "readys (P th cs # s) \<subseteq> readys s"
       
   547 apply(auto simp add: readys_def waits2_def Let_def)
       
   548 apply(simp add: waits_def)
       
   549 apply(case_tac "csa = cs")
       
   550 apply(simp)
       
   551 apply(drule_tac x="cs" in spec)
       
   552 apply(simp)
       
   553 apply (metis hd_append2 in_set_insert insert_Nil list.sel(1))
       
   554 apply(drule_tac x="csa" in spec)
       
   555 apply(simp)
       
   556 done
       
   557 
       
   558 lemma readys_V:
       
   559   shows "readys (V th cs # s) \<subseteq> readys s \<union> set (wq s cs)"
       
   560 apply(auto simp add: readys_def waits2_def waits_def Let_def wq_def)
       
   561 done
       
   562 
       
   563 
       
   564 fun the_th :: "node \<Rightarrow> thread"
       
   565   where "the_th (Th th) = th"
       
   566 
       
   567 lemma image_Collect2:
       
   568   "f ` A = {f x | x. x \<in> A}"
       
   569 apply(auto)
       
   570 done
       
   571 
       
   572 lemma Collect_disj_eq2:
       
   573   "{f x | x. x = y \<or> x \<in> A} = {f y} \<union> {f x | x. x \<in> A}"
       
   574 by (auto)
       
   575 
       
   576 lemma last_set_lt: 
       
   577   "th \<in> threads s \<Longrightarrow> last_set th s < length s"
       
   578   apply(induct rule: threads.induct)
       
   579   apply(auto)
       
   580   done
       
   581 
       
   582 lemma last_set_eq_iff: 
       
   583   assumes "th1 \<in> threads s" "th2 \<in> threads s"
       
   584   shows "last_set th1 s = last_set th2 s \<longleftrightarrow> th1 = th2"
       
   585   using assms
       
   586   apply(induct s rule: threads.induct) 
       
   587   apply(auto split:if_splits dest:last_set_lt)
       
   588   done
       
   589 
       
   590 lemma preced_eq_iff: 
       
   591   assumes th_in1: "th1 \<in> threads s"
       
   592   and th_in2: "th2 \<in> threads s"
       
   593   shows "preced th1 s = preced th2 s \<longleftrightarrow> th1 = th2"
       
   594 using assms
       
   595 by (auto simp add: preced_def last_set_eq_iff)
       
   596 
       
   597 lemma dm_RAG_threads:
       
   598   assumes vt: "vt s"
       
   599   and in_dom: "(Th th) \<in> Domain (RAG2 s)"
       
   600   shows "th \<in> threads s"
       
   601 proof -
       
   602   from in_dom obtain n where a: "(Th th, n) \<in> RAG2 s" by auto
       
   603   then obtain cs where "n = Cs cs" 
       
   604     unfolding RAG2_def RAG_def
       
   605     by auto
       
   606   then have "(Th th, Cs cs) \<in> RAG2 s" using a by simp
       
   607   hence "th \<in> set (wq s cs)"
       
   608     unfolding RAG2_def wq_def RAG_def waits_def
       
   609     by (auto)
       
   610   then show ?thesis
       
   611     apply(rule_tac wq_threads)
       
   612     apply(rule assms)
       
   613     apply(simp)
       
   614     done
       
   615 qed
       
   616 
       
   617 lemma cpreced_eq_iff:
       
   618   assumes "th1 \<in> readys s" "th2 \<in> readys s" "vt s"
       
   619   shows "cpreced2 s th1 = cpreced2 s th2 \<longleftrightarrow> th1 = th2" 
       
   620 proof 
       
   621   def S1\<equiv>"({th1} \<union> dependants (wq s) th1)"
       
   622   def S2\<equiv>"({th2} \<union> dependants (wq s) th2)"
       
   623   have fin: "finite ((the_th o fst) ` ((RAG (wq s))\<^sup>+))" 
       
   624       apply(rule)
       
   625       apply(simp add: finite_trancl)
       
   626       apply(simp add: wq_def)
       
   627       apply(rule finite_RAG[simplified RAG2_def])
       
   628       apply(rule assms)
       
   629       done
       
   630 
       
   631   from fin have h: "finite (preceds s S1)" "finite (preceds s S2)"
       
   632       apply(simp_all add: S2_def S1_def Collect_disj_eq2 image_Collect[symmetric])
       
   633       apply(rule)
       
   634       apply(simp add: dependants_def)  
       
   635       apply(rule rev_finite_subset)
       
   636       apply(assumption)
       
   637       apply(auto simp add: image_def)[1]
       
   638       apply(metis fst_conv the_th.simps)
       
   639       apply(rule)
       
   640       apply(simp add: dependants_def)  
       
   641       apply(rule rev_finite_subset)
       
   642       apply(assumption)
       
   643       apply(auto simp add: image_def)[1]
       
   644       apply(metis fst_conv the_th.simps)
       
   645       done
       
   646     moreover have "S1 \<noteq> {}" "S2 \<noteq> {}" by (simp_all add: S1_def S2_def)
       
   647     then have "(preceds s S1) \<noteq> {}" "(preceds s S2) \<noteq> {}" by simp_all
       
   648     ultimately have m: "Max (preceds s S1) \<in> (preceds s S1)" "Max (preceds s S2) \<in> (preceds s S2)"
       
   649       apply(rule_tac [!] Max_in)
       
   650       apply(simp_all)
       
   651       done
       
   652 
       
   653   assume q: "cpreced2 s th1 = cpreced2 s th2"
       
   654   then have eq_max: "Max (preceds s S1) = Max (preceds s S2)"
       
   655     unfolding cpreced2_cpreced cpreced_def
       
   656     apply(simp only: S1_def S2_def)
       
   657     apply(simp add: Collect_disj_eq2)
       
   658     done
       
   659  
       
   660   obtain th0 where th0_in: "th0 \<in> S1" "th0 \<in> S2" and 
       
   661       eq_f_th1: "preced th0 s = Max (preceds s S1)"
       
   662                 "preced th0 s = Max (preceds s S2)"
       
   663     using m 
       
   664       apply(clarify)
       
   665       apply(simp add: eq_max)
       
   666       apply(subst (asm) (2)  preced_eq_iff)
       
   667       apply(insert assms(2))[1]
       
   668       apply(simp add: S2_def)
       
   669       apply(auto)[1]
       
   670       apply (metis contra_subsetD readys_threads)
       
   671       apply(simp add: dependants_def)
       
   672       apply(subgoal_tac "Th tha \<in> Domain ((RAG2 s)^+)")
       
   673       apply(simp add: trancl_domain)
       
   674       apply (metis Domain_RAG_threads assms(3))
       
   675       apply(simp only: RAG2_def wq_def)
       
   676       apply (metis Domain_iff)
       
   677       apply(insert assms(1))[1]
       
   678       apply(simp add: S1_def)
       
   679       apply(auto)[1]
       
   680       apply (metis contra_subsetD readys_threads)
       
   681       apply(simp add: dependants_def)
       
   682       apply(subgoal_tac "Th th \<in> Domain ((RAG2 s)^+)")
       
   683       apply(simp add: trancl_domain)
       
   684       apply (metis Domain_RAG_threads assms(3))
       
   685       apply(simp only: RAG2_def wq_def)
       
   686       apply (metis Domain_iff)
       
   687       apply(simp)
       
   688     done
       
   689   then show "th1 = th2"
       
   690     apply -
       
   691     apply(insert th0_in assms(1, 2))[1]
       
   692     apply(simp add: S1_def S2_def)
       
   693     apply(auto)
       
   694     --"first case"
       
   695     prefer 2
       
   696     apply(subgoal_tac "Th th2 \<in> Domain (RAG2 s)")
       
   697     apply(subgoal_tac "\<exists>cs. (Th th2, Cs cs) \<in> RAG2 s")
       
   698     apply(erule exE)
       
   699     apply(simp add: runing_def RAG2_def RAG_def readys_def waits2_def)[1]
       
   700     apply(auto simp add: RAG2_def RAG_def)[1]
       
   701     apply(subgoal_tac "Th th2 \<in> Domain ((RAG2 s)^+)")
       
   702     apply (metis trancl_domain)
       
   703     apply(subgoal_tac "(Th th2, Th th1) \<in> (RAG2 s)^+")
       
   704     apply (metis Domain_iff)
       
   705     apply(simp add: dependants_def RAG2_def wq_def)
       
   706     --"second case"
       
   707     apply(subgoal_tac "Th th1 \<in> Domain (RAG2 s)")
       
   708     apply(subgoal_tac "\<exists>cs. (Th th1, Cs cs) \<in> RAG2 s")
       
   709     apply(erule exE)
       
   710     apply(insert assms(1))[1]
       
   711     apply(simp add: runing_def RAG2_def RAG_def readys_def waits2_def)[1]
       
   712     apply(auto simp add: RAG2_def RAG_def)[1]
       
   713     apply(subgoal_tac "Th th1 \<in> Domain ((RAG2 s)^+)")
       
   714     apply (metis trancl_domain)
       
   715     apply(subgoal_tac "(Th th1, Th th2) \<in> (RAG2 s)^+")
       
   716     apply (metis Domain_iff)
       
   717     apply(simp add: dependants_def RAG2_def wq_def)
       
   718     --"third case"
       
   719     apply(rule dchain_unique)
       
   720     apply(rule assms(3))
       
   721     apply(simp add: dependants_def RAG2_def wq_def)
       
   722     apply(simp)
       
   723     apply(simp add: dependants_def RAG2_def wq_def)
       
   724     apply(simp)
       
   725     done
       
   726 next
       
   727   assume "th1 = th2"
       
   728   then show "cpreced2 s th1 = cpreced2 s th2" by simp
       
   729 qed
       
   730 
       
   731 lemma at_most_one_running:
       
   732   assumes "vt s"
       
   733   shows "card (runing s) \<le> 1"
       
   734 proof (rule ccontr)
       
   735   assume "\<not> card (runing s) \<le> 1"
       
   736   then have "2 \<le> card (runing s)" by auto
       
   737   moreover 
       
   738   have "finite (runing s)"
       
   739     by (metis `\<not> card (runing s) \<le> 1` card_infinite le0)
       
   740   ultimately obtain th1 th2 where a: 
       
   741     "th1 \<noteq> th2" "th1 \<in> runing s" "th2 \<in> runing s" 
       
   742     "cpreced2 s th1 = cpreced2 s th2" 
       
   743     apply(auto simp add: numerals card_le_Suc_iff runing_def) 
       
   744     apply(blast)
       
   745     done
       
   746   then have "th1 = th2"
       
   747     apply(subst (asm) cpreced_eq_iff)
       
   748     apply(auto intro: assms a)
       
   749     apply (metis contra_subsetD runing_ready)+
       
   750     done
       
   751   then show "False" using a(1) by auto
       
   752 qed
       
   753 
       
   754 
       
   755 
       
   756   (*
       
   757   obtain th0 where th0_in: "th0 \<in> S1 \<and> th0 \<in> S2" 
       
   758     and eq_f_th0: "preced th0 s = Max ((\<lambda>th. preced th s) ` (S1 \<inter> S2))"
       
   759   proof -
       
   760     from fin have h1: "finite ((\<lambda>th. preced th s) ` (S1 \<inter> S2))"
       
   761       apply(simp only: S1_def S2_def)
       
   762       apply(rule)
       
   763       apply(rule)
       
   764       apply(rule)
       
   765       apply(simp add: dependants_def) 
       
   766       apply(rule rev_finite_subset)
       
   767       apply(assumption)
       
   768       apply(auto simp add: image_def)
       
   769       apply (metis fst_conv the_th.simps)
       
   770       done
       
   771     moreover 
       
   772     have "S1 \<inter> S2 \<noteq> {}" apply (simp add: S1_def S2_def) 
       
   773       apply(auto) 
       
   774       
       
   775       done
       
   776     then have h2: "((\<lambda>th. preced th s) ` (S1 \<union> S2)) \<noteq> {}" by simp
       
   777     ultimately have "Max ((\<lambda>th. preced th s) ` (S1 \<union> S2)) \<in> ((\<lambda>th. preced th s) ` (S1 \<union> S2))"
       
   778       apply(rule Max_in)
       
   779       done
       
   780     then show ?thesis using that[intro] apply(auto) 
       
   781       
       
   782       apply(erule_tac preced_unique)
       
   783       done
       
   784   qed
       
   785   *)
       
   786 
       
   787 thm waits_def waits2_def
       
   788 
       
   789 end