Correctness.thy~
changeset 67 25fd656667a7
parent 66 2af87bb52fca
child 68 db196b066b97
equal deleted inserted replaced
66:2af87bb52fca 67:25fd656667a7
    77     by (unfold vat_s.cp_rec, rule Max_ge, 
    77     by (unfold vat_s.cp_rec, rule Max_ge, 
    78         auto simp:the_preced_def vat_s.fsbttRAGs.finite_children)
    78         auto simp:the_preced_def vat_s.fsbttRAGs.finite_children)
    79   ultimately show ?thesis by auto
    79   ultimately show ?thesis by auto
    80 qed
    80 qed
    81 
    81 
    82 (* ccc *)
       
    83 lemma highest_cp_preced: "cp s th = Max ((\<lambda> th'. preced th' s) ` threads s)"
    82 lemma highest_cp_preced: "cp s th = Max ((\<lambda> th'. preced th' s) ` threads s)"
    84   by (fold max_cp_eq, unfold eq_cp_s_th, insert highest, simp)
    83   by (fold max_cp_eq, unfold eq_cp_s_th, insert highest, simp)
    85 
    84 
    86 lemma highest_preced_thread: "preced th s = Max ((\<lambda> th'. preced th' s) ` threads s)"
    85 lemma highest_preced_thread: "preced th s = Max ((\<lambda> th'. preced th' s) ` threads s)"
    87   by (fold eq_cp_s_th, unfold highest_cp_preced, simp)
    86   by (fold eq_cp_s_th, unfold highest_cp_preced, simp)
   132 
   131 
   133 sublocale red_extend_highest_gen <   red_moment: extend_highest_gen "s" "th" "prio" "tm" "(moment i t)"
   132 sublocale red_extend_highest_gen <   red_moment: extend_highest_gen "s" "th" "prio" "tm" "(moment i t)"
   134   apply (insert extend_highest_gen_axioms, subst (asm) (1) moment_restm_s [of i t, symmetric])
   133   apply (insert extend_highest_gen_axioms, subst (asm) (1) moment_restm_s [of i t, symmetric])
   135   apply (unfold extend_highest_gen_def extend_highest_gen_axioms_def, clarsimp)
   134   apply (unfold extend_highest_gen_def extend_highest_gen_axioms_def, clarsimp)
   136   by (unfold highest_gen_def, auto dest:step_back_vt_app)
   135   by (unfold highest_gen_def, auto dest:step_back_vt_app)
   137 
       
   138 
   136 
   139 context extend_highest_gen
   137 context extend_highest_gen
   140 begin
   138 begin
   141 
   139 
   142  lemma ind [consumes 0, case_names Nil Cons, induct type]:
   140  lemma ind [consumes 0, case_names Nil Cons, induct type]:
   456 by (metis Max.coboundedI finite_imageI highest not_le order.trans 
   454 by (metis Max.coboundedI finite_imageI highest not_le order.trans 
   457     preced_linorder rev_image_eqI threads_s vat_s.finite_threads 
   455     preced_linorder rev_image_eqI threads_s vat_s.finite_threads 
   458     vat_s.le_cp)
   456     vat_s.le_cp)
   459 
   457 
   460 text {*
   458 text {*
       
   459   The following lemmas shows that the @{term cp}-value 
       
   460   of the blocking thread @{text th'} equals to the highest
       
   461   precedence in the whole system.
       
   462 *}
       
   463 lemma runing_preced_inversion:
       
   464   assumes runing': "th' \<in> runing (t@s)"
       
   465   shows "cp (t@s) th' = preced th s" (is "?L = ?R")
       
   466 proof -
       
   467   have "?L = Max (cp (t @ s) ` readys (t @ s))" using assms
       
   468       by (unfold runing_def, auto)
       
   469   also have "\<dots> = ?R"
       
   470       by (metis th_cp_max th_cp_preced vat_t.max_cp_readys_threads) 
       
   471   finally show ?thesis .
       
   472 qed
       
   473 
       
   474 
       
   475 text {*
   461   Counting of the number of @{term "P"} and @{term "V"} operations 
   476   Counting of the number of @{term "P"} and @{term "V"} operations 
   462   is the cornerstone of a large number of the following proofs. 
   477   is the cornerstone of a large number of the following proofs. 
   463   The reason is that this counting is quite easy to calculate and 
   478   The reason is that this counting is quite easy to calculate and 
   464   convenient to use in the reasoning. 
   479   convenient to use in the reasoning. 
   465 
   480 
   466   The following lemma shows that the counting controls whether 
   481   The following lemma shows that the counting controls whether 
   467   a thread is running or not.
   482   a thread is running or not.
   468 *}
   483 *} (* ccc *)
   469 
   484                       
   470 lemma pv_blocked_pre: (* ddd *)
   485 lemma eq_pv_blocked: (* ddd *)
   471   assumes th'_in: "th' \<in> threads (t@s)"
   486   assumes neq_th': "th' \<noteq> th"
   472   and neq_th': "th' \<noteq> th"
       
   473   and eq_pv: "cntP (t@s) th' = cntV (t@s) th'"
   487   and eq_pv: "cntP (t@s) th' = cntV (t@s) th'"
   474   shows "th' \<notin> runing (t@s)"
   488   shows "th' \<notin> runing (t@s)"
   475 proof
   489 proof
   476   assume otherwise: "th' \<in> runing (t@s)"
   490   assume otherwise: "th' \<in> runing (t@s)"
   477   show False
   491   show False
   478   proof -
   492   proof -
       
   493     have th'_in: "th' \<in> threads (t@s)"
       
   494         using otherwise readys_threads runing_def by auto 
   479     have "th' = th"
   495     have "th' = th"
   480     proof(rule preced_unique)
   496     proof(rule preced_unique)
       
   497       -- {* The proof goes like this: 
       
   498             it is first shown that the @{term preced}-value of @{term th'} 
       
   499             equals to that of @{term th}, then by uniqueness 
       
   500             of @{term preced}-values (given by lemma @{thm preced_unique}), 
       
   501             @{term th'} equals to @{term th}: *}
   481       show "preced th' (t @ s) = preced th (t @ s)" (is "?L = ?R")
   502       show "preced th' (t @ s) = preced th (t @ s)" (is "?L = ?R")
   482       proof -
   503       proof -
       
   504         -- {* Since the counts of @{term th'} are balanced, the subtree
       
   505               of it contains only itself, so, its @{term cp}-value
       
   506               equals its @{term preced}-value: *}
   483         have "?L = cp (t@s) th'"
   507         have "?L = cp (t@s) th'"
   484           by (unfold cp_eq_cpreced cpreced_def count_eq_dependants[OF eq_pv], simp)
   508           by (unfold cp_eq_cpreced cpreced_def count_eq_dependants[OF eq_pv], simp)
   485         also have "... = cp (t @ s) th" using otherwise 
   509         -- {* Since @{term "th'"} is running by @{thm otherwise},
   486           by (metis (mono_tags, lifting) mem_Collect_eq 
   510               it has the highest @{term cp}-value, by definition, 
   487                     runing_def th_cp_max vat_t.max_cp_readys_threads)
   511               which in turn equals to the @{term cp}-value of @{term th}. *}
   488         also have "... = ?R" by (metis th_cp_preced th_kept) 
   512         also have "... = ?R" 
       
   513             using runing_preced_inversion[OF otherwise] th_kept by simp
   489         finally show ?thesis .
   514         finally show ?thesis .
   490       qed
   515       qed
   491     qed (auto simp: th'_in th_kept)
   516     qed (auto simp: th'_in th_kept)
   492     moreover have "th' \<noteq> th" using neq_th' .
   517     moreover have "th' \<noteq> th" using neq_th' .
   493     ultimately show ?thesis by simp
   518     ultimately show ?thesis by simp
   494  qed
   519  qed
   495 qed
   520 qed
   496 
   521 
   497 lemmas pv_blocked = pv_blocked_pre[folded detached_eq]
   522 lemmas eq_pv_blocked_dtc = eq_pv_blocked[folded detached_eq]
   498 
   523 
   499 lemma runing_precond_pre: (* ddd *)
   524 
   500   fixes th'
   525 
       
   526 lemma eq_pv_kept: (* ddd *)
   501   assumes th'_in: "th' \<in> threads s"
   527   assumes th'_in: "th' \<in> threads s"
   502   and eq_pv: "cntP s th' = cntV s th'"
   528   and eq_pv: "cntP s th' = cntV s th'"
   503   and neq_th': "th' \<noteq> th"
   529   and neq_th': "th' \<noteq> th"
   504   shows "th' \<in> threads (t@s) \<and>
   530   shows "th' \<in> threads (t@s) \<and>
   505          cntP (t@s) th' = cntV (t@s) th'"
   531          cntP (t@s) th' = cntV (t@s) th'"
   519             have "step (t@s) (P thread cs)" using Cons P by auto
   545             have "step (t@s) (P thread cs)" using Cons P by auto
   520             thus ?thesis
   546             thus ?thesis
   521             proof(cases)
   547             proof(cases)
   522               assume "thread \<in> runing (t@s)"
   548               assume "thread \<in> runing (t@s)"
   523               moreover have "th' \<notin> runing (t@s)" using Cons(5)
   549               moreover have "th' \<notin> runing (t@s)" using Cons(5)
   524                 by (metis neq_th' vat_t.pv_blocked_pre) 
   550                 by (metis neq_th' vat_t.eq_pv_blocked) 
   525               ultimately show ?thesis by auto
   551               ultimately show ?thesis by auto
   526             qed
   552             qed
   527           qed with Cons show ?thesis
   553           qed with Cons show ?thesis
   528             by (unfold P, simp add:cntP_def cntV_def count_def)
   554             by (unfold P, simp add:cntP_def cntV_def count_def)
   529         qed
   555         qed
   541             have "step (t@s) (V thread cs)" using Cons V by auto
   567             have "step (t@s) (V thread cs)" using Cons V by auto
   542             thus ?thesis
   568             thus ?thesis
   543             proof(cases)
   569             proof(cases)
   544               assume "thread \<in> runing (t@s)"
   570               assume "thread \<in> runing (t@s)"
   545               moreover have "th' \<notin> runing (t@s)" using Cons(5)
   571               moreover have "th' \<notin> runing (t@s)" using Cons(5)
   546                 by (metis neq_th' vat_t.pv_blocked_pre) 
   572                 by (metis neq_th' vat_t.eq_pv_blocked) 
   547               ultimately show ?thesis by auto
   573               ultimately show ?thesis by auto
   548             qed
   574             qed
   549           qed with Cons show ?thesis
   575           qed with Cons show ?thesis
   550             by (unfold V, simp add:cntP_def cntV_def count_def)
   576             by (unfold V, simp add:cntP_def cntV_def count_def)
   551         qed
   577         qed
   574       proof -
   600       proof -
   575         have neq_thread: "thread \<noteq> th'"
   601         have neq_thread: "thread \<noteq> th'"
   576         proof -
   602         proof -
   577           have "step (t@s) (Exit thread)" using Cons Exit by auto
   603           have "step (t@s) (Exit thread)" using Cons Exit by auto
   578           thus ?thesis apply (cases) using Cons(5)
   604           thus ?thesis apply (cases) using Cons(5)
   579                 by (metis neq_th' vat_t.pv_blocked_pre) 
   605                 by (metis neq_th' vat_t.eq_pv_blocked) 
   580         qed 
   606         qed 
   581         hence "cntP ((e # t) @ s) th' = cntV ((e # t) @ s) th'" using Cons
   607         hence "cntP ((e # t) @ s) th' = cntV ((e # t) @ s) th'" using Cons
   582             by (unfold Exit, simp add:cntP_def cntV_def count_def)
   608             by (unfold Exit, simp add:cntP_def cntV_def count_def)
   583         moreover have "th' \<in> threads ((e # t) @ s)" using Cons neq_thread 
   609         moreover have "th' \<in> threads ((e # t) @ s)" using Cons neq_thread 
   584           by (unfold Exit, simp) 
   610           by (unfold Exit, simp) 
   594   case Nil
   620   case Nil
   595   with assms
   621   with assms
   596   show ?case by auto
   622   show ?case by auto
   597 qed
   623 qed
   598 
   624 
       
   625 (* runing_precond has changed to eq_pv_kept *)
       
   626 
   599 text {* Changing counting balance to detachedness *}
   627 text {* Changing counting balance to detachedness *}
   600 lemmas runing_precond_pre_dtc = runing_precond_pre
   628 lemmas eq_pv_kept_dtc = eq_pv_kept
   601          [folded vat_t.detached_eq vat_s.detached_eq]
   629          [folded vat_t.detached_eq vat_s.detached_eq]
   602 
   630 
   603 lemma runing_precond: (* ddd *)
   631 section {* The blocking thread *}
   604   fixes th'
   632 
       
   633 text {* 
       
   634   The purpose of PIP is to ensure that the most 
       
   635   urgent thread @{term th} is not blocked unreasonably. 
       
   636   Therefore, a clear picture of the blocking thread is essential 
       
   637   to assure people that the purpose is fulfilled. 
       
   638   
       
   639   The following lemmas will give us such a picture: 
       
   640 *}
       
   641 
       
   642 (* ccc *)
       
   643 
       
   644 text {*
       
   645   The following lemma shows the blocking thread @{term th'}
       
   646   must hold some resource in the very beginning. 
       
   647 *}
       
   648 lemma runing_cntP_cntV_inv: (* ddd *)
   605   assumes th'_in: "th' \<in> threads s"
   649   assumes th'_in: "th' \<in> threads s"
   606   and neq_th': "th' \<noteq> th"
   650   and neq_th': "th' \<noteq> th"
   607   and is_runing: "th' \<in> runing (t@s)"
   651   and is_runing: "th' \<in> runing (t@s)"
   608   shows "cntP s th' > cntV s th'"
   652   shows "cntP s th' > cntV s th'"
   609   using assms
   653   using assms
   610 proof -
   654 proof - (* ccc *)
       
   655   -- {* First, it can be shown that the number of @{term P} and
       
   656         @{term V} operations can not be equal for thred @{term th'} *}
   611   have "cntP s th' \<noteq> cntV s th'"
   657   have "cntP s th' \<noteq> cntV s th'"
   612     by (metis is_runing neq_th' pv_blocked_pre runing_precond_pre th'_in)
   658   proof
       
   659     assume otherwise: "cntP s th' = cntV s th'"
       
   660     -- {* The proof goes by contradiction. *}
       
   661     -- {* We can show that @{term th'} can not be running at moment @{term "t@s"}: *}
       
   662     have "th' \<notin> runing (t@s)" 
       
   663     proof(rule eq_pv_blocked)
       
   664       show "th' \<noteq> th" using neq_th' by simp
       
   665     next
       
   666       show "cntP (t @ s) th' = cntV (t @ s) th'"
       
   667         using eq_pv_kept[OF th'_in otherwise neq_th'] by simp
       
   668     qed
       
   669     -- {* This is obvious in contradiction with assumption @{thm is_runing}  *}
       
   670     thus False using is_runing by simp
       
   671   qed
   613   moreover have "cntV s th' \<le> cntP s th'" using vat_s.cnp_cnv_cncs by auto
   672   moreover have "cntV s th' \<le> cntP s th'" using vat_s.cnp_cnv_cncs by auto
   614   ultimately show ?thesis by auto
   673   ultimately show ?thesis by auto
   615 qed
   674 qed
   616 
   675 
   617 lemma moment_blocked_pre:
   676 lemma moment_blocked_pre:
   654     assume "Exit th' \<in> set (moment j (restm i t))"
   713     assume "Exit th' \<in> set (moment j (restm i t))"
   655     thus "th' \<noteq> th"
   714     thus "th' \<noteq> th"
   656       by (metis Un_iff add.commute h_j.exit_diff moment_plus_split set_append)
   715       by (metis Un_iff add.commute h_j.exit_diff moment_plus_split set_append)
   657   qed
   716   qed
   658   show ?thesis 
   717   show ?thesis 
   659     by (metis add.commute append_assoc eq_pv h.runing_precond_pre
   718     by (metis add.commute append_assoc eq_pv h.eq_pv_kept
   660           moment_plus_split neq_th' th'_in)
   719           moment_plus_split neq_th' th'_in)
   661 qed
   720 qed
   662 
   721 
   663 lemma moment_blocked_eqpv: (* ddd *)
   722 lemma moment_blocked_eqpv: (* ddd *)
   664   assumes neq_th': "th' \<noteq> th"
   723   assumes neq_th': "th' \<noteq> th"
   674    and h2: "th' \<in> threads ((moment j t)@s)" by auto
   733    and h2: "th' \<in> threads ((moment j t)@s)" by auto
   675   moreover have "th' \<notin> runing ((moment j t)@s)"
   734   moreover have "th' \<notin> runing ((moment j t)@s)"
   676   proof -
   735   proof -
   677     interpret h: red_extend_highest_gen _ _ _ _ _ j by (unfold_locales)
   736     interpret h: red_extend_highest_gen _ _ _ _ _ j by (unfold_locales)
   678     show ?thesis
   737     show ?thesis
   679       using h.pv_blocked_pre h1 h2 neq_th' by auto 
   738       using h.eq_pv_blocked h1 h2 neq_th' by auto 
   680   qed
   739   qed
   681   ultimately show ?thesis by auto
   740   ultimately show ?thesis by auto
   682 qed
   741 qed
   683 
   742 
   684 (* The foregoing two lemmas are preparation for this one, but
   743 (* The foregoing two lemmas are preparation for this one, but
   685    in long run can be combined. Maybe I am wrong.
   744    in long run can be combined. Maybe I am wrong.
       
   745    This one is useless (* XY *)
   686 *)
   746 *)
   687 lemma moment_blocked:
   747 lemma moment_blocked:
   688   assumes neq_th': "th' \<noteq> th"
   748   assumes neq_th': "th' \<noteq> th"
   689   and th'_in: "th' \<in> threads ((moment i t)@s)"
   749   and th'_in: "th' \<in> threads ((moment i t)@s)"
   690   and dtc: "detached (moment i t @ s) th'"
   750   and dtc: "detached (moment i t @ s) th'"
   699                 by (metis dtc h_i.detached_elim)
   759                 by (metis dtc h_i.detached_elim)
   700   from moment_blocked_eqpv[OF neq_th' th'_in cnt_i le_ij]
   760   from moment_blocked_eqpv[OF neq_th' th'_in cnt_i le_ij]
   701   show ?thesis by (metis h_j.detached_intro) 
   761   show ?thesis by (metis h_j.detached_intro) 
   702 qed
   762 qed
   703 
   763 
   704 lemma runing_preced_inversion:
   764 text {*
       
   765   The following lemmas shows the blocking thread @{text th'} must be live 
       
   766   at the very beginning, i.e. the moment (or state) @{term s}. 
       
   767 *}
       
   768 lemma runing_threads_inv: (* ddd *) (* ccc *)
   705   assumes runing': "th' \<in> runing (t@s)"
   769   assumes runing': "th' \<in> runing (t@s)"
   706   shows "cp (t@s) th' = preced th s" (is "?L = ?R")
   770   and neq_th': "th' \<noteq> th"
   707 proof -
       
   708   have "?L = Max (cp (t @ s) ` readys (t @ s))" using assms
       
   709       by (unfold runing_def, auto)
       
   710   also have "\<dots> = ?R"
       
   711       by (metis th_cp_max th_cp_preced vat_t.max_cp_readys_threads) 
       
   712   finally show ?thesis .
       
   713 qed
       
   714 
       
   715 text {*
       
   716   The situation when @{term "th"} is blocked is analyzed by the following lemmas.
       
   717 *}
       
   718 
       
   719 text {*
       
   720   The following lemmas shows the running thread @{text "th'"}, if it is different from
       
   721   @{term th}, must be live at the very beginning. By the term {\em the very beginning},
       
   722   we mean the moment where the formal investigation starts, i.e. the moment (or state)
       
   723   @{term s}. 
       
   724 *}
       
   725 
       
   726 lemma runing_inversion_0:
       
   727   assumes neq_th': "th' \<noteq> th"
       
   728   and runing': "th' \<in> runing (t@s)"
       
   729   shows "th' \<in> threads s"
   771   shows "th' \<in> threads s"
   730 proof -
   772 proof -
   731     -- {* The proof is by contradiction: *}
   773     -- {* The proof is by contradiction: *}
   732     { assume otherwise: "\<not> ?thesis"
   774     { assume otherwise: "\<not> ?thesis"
   733       have "th' \<notin> runing (t @ s)"
   775       have "th' \<notin> runing (t @ s)"
   772       with `th' \<in> runing (t@s)`
   814       with `th' \<in> runing (t@s)`
   773       have False by simp
   815       have False by simp
   774     } thus ?thesis by auto
   816     } thus ?thesis by auto
   775 qed
   817 qed
   776 
   818 
   777 text {* 
   819 text {*
   778   The second lemma says, if the running thread @{text th'} is different from 
   820   The following lemma summarizes several foregoing 
   779   @{term th}, then this @{text th'} must in the possession of some resources
   821   lemmas to give an overall picture of the blocking thread @{text "th'"}:
   780   at the very beginning. 
   822 *}
   781 
   823 lemma runing_inversion:
   782   To ease the reasoning of resource possession of one particular thread, 
       
   783   we used two auxiliary functions @{term cntV} and @{term cntP}, 
       
   784   which are the counters of @{term P}-operations and 
       
   785   @{term V}-operations respectively. 
       
   786   If the number of @{term V}-operation is less than the number of 
       
   787   @{term "P"}-operations, the thread must have some unreleased resource. 
       
   788 *}
       
   789 
       
   790 lemma runing_inversion_1: (* ddd *)
       
   791   assumes neq_th': "th' \<noteq> th"
       
   792   and runing': "th' \<in> runing (t@s)"
       
   793   -- {* thread @{term "th'"} is a live on in state @{term "s"} and 
       
   794         it has some unreleased resource. *}
       
   795   shows "th' \<in> threads s \<and> cntV s th' < cntP s th'"
       
   796 proof -
       
   797   -- {* The proof is a simple composition of @{thm runing_inversion_0} and 
       
   798         @{thm runing_precond}: *}
       
   799   -- {* By applying @{thm runing_inversion_0} to assumptions,
       
   800         it can be shown that @{term th'} is live in state @{term s}: *}
       
   801   have "th' \<in> threads s"  using runing_inversion_0[OF assms(1,2)] .
       
   802   -- {* Then the thesis is derived easily by applying @{thm runing_precond}: *}
       
   803   with runing_precond [OF this neq_th' runing'] show ?thesis by simp
       
   804 qed
       
   805 
       
   806 text {* 
       
   807   The following lemma is just a rephrasing of @{thm runing_inversion_1}:
       
   808 *}
       
   809 lemma runing_inversion_2:
       
   810   assumes runing': "th' \<in> runing (t@s)"
       
   811   shows "th' = th \<or> (th' \<noteq> th \<and> th' \<in> threads s \<and> cntV s th' < cntP s th')"
       
   812 proof -
       
   813   from runing_inversion_1[OF _ runing']
       
   814   show ?thesis by auto
       
   815 qed
       
   816 
       
   817 lemma runing_inversion_3:
       
   818   assumes runing': "th' \<in> runing (t@s)"
       
   819   and neq_th: "th' \<noteq> th"
       
   820   shows "th' \<in> threads s \<and> (cntV s th' < cntP s th' \<and> cp (t@s) th' = preced th s)"
       
   821   by (metis neq_th runing' runing_inversion_2 runing_preced_inversion)
       
   822 
       
   823 lemma runing_inversion_4:
       
   824   assumes runing': "th' \<in> runing (t@s)"
   824   assumes runing': "th' \<in> runing (t@s)"
   825   and neq_th: "th' \<noteq> th"
   825   and neq_th: "th' \<noteq> th"
   826   shows "th' \<in> threads s"
   826   shows "th' \<in> threads s"
   827   and    "\<not>detached s th'"
   827   and    "\<not>detached s th'"
   828   and    "cp (t@s) th' = preced th s"
   828   and    "cp (t@s) th' = preced th s"
   829   apply (metis neq_th runing' runing_inversion_2)
   829 proof -
   830   apply (metis neq_th pv_blocked runing' runing_inversion_2 runing_precond_pre_dtc)
   830   from runing_threads_inv[OF assms]
   831   by (metis neq_th runing' runing_inversion_3)
   831   show "th' \<in> threads s" .
       
   832 next
       
   833   from runing_cntP_cntV_inv[OF runing_threads_inv[OF assms] neq_th runing']
       
   834   show "\<not>detached s th'" using vat_s.detached_eq by simp
       
   835 next
       
   836   from runing_preced_inversion[OF runing']
       
   837   show "cp (t@s) th' = preced th s" .
       
   838 qed
   832 
   839 
   833 text {* 
   840 text {* 
   834   Suppose @{term th} is not running, it is first shown that
   841   Suppose @{term th} is not running, it is first shown that
   835   there is a path in RAG leading from node @{term th} to another thread @{text "th'"} 
   842   there is a path in RAG leading from node @{term th} to another thread @{text "th'"} 
   836   in the @{term readys}-set (So @{text "th'"} is an ancestor of @{term th}}).
   843   in the @{term readys}-set (So @{text "th'"} is an ancestor of @{term th}}).