PIPDefs.thy
changeset 118 a4bb5525b7b6
parent 115 74fc1eae4605
child 125 95e7933968f8
equal deleted inserted replaced
117:8a6125caead2 118:a4bb5525b7b6
   161   The thread at the head of this list is designated as the thread which is current 
   161   The thread at the head of this list is designated as the thread which is current 
   162   holding the resrouce, which is slightly different from tradition where
   162   holding the resrouce, which is slightly different from tradition where
   163   all threads in the waiting queue are considered as waiting for the resource.
   163   all threads in the waiting queue are considered as waiting for the resource.
   164   *}
   164   *}
   165 
   165 
       
   166 (*
   166 consts 
   167 consts 
   167   holding :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool" 
   168   holding :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool" 
   168   waiting :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool"
   169   waiting :: "'b \<Rightarrow> thread \<Rightarrow> cs \<Rightarrow> bool"
   169   RAG :: "'b \<Rightarrow> (node \<times> node) set"
   170   RAG :: "'b \<Rightarrow> (node \<times> node) set"
   170   dependants :: "'b \<Rightarrow> thread \<Rightarrow> thread set"
   171   dependants :: "'b \<Rightarrow> thread \<Rightarrow> thread set"
   171 
   172 *)
   172 defs (overloaded) 
   173 
       
   174 definition 
   173   -- {* 
   175   -- {* 
   174   \begin{minipage}{0.9\textwidth}
   176   \begin{minipage}{0.9\textwidth}
   175   This meaning of @{text "wq"} is reflected in the following definition of @{text "holding wq th cs"},
   177   This meaning of @{text "wq"} is reflected in the following definition of
   176   where @{text "holding wq th cs"} means thread @{text "th"} is holding the critical 
   178   @{text "holding wq th cs"}, where @{text "holding wq th cs"} means thread
   177   resource @{text "cs"}. This decision is based on @{text "wq"}.
   179   @{text "th"} is holding the critical resource @{text "cs"}. This decision
   178   \end{minipage}
   180   is based on @{text "wq"}.
   179   *}
   181   \end{minipage}
   180 
   182   *}
   181   cs_holding_def: 
   183 
   182   "holding wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread = hd (wq cs))"
   184   cs_holding_raw:   
       
   185   "holding_raw wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread = hd (wq cs))"
       
   186 
       
   187 
       
   188 definition
   183   -- {* 
   189   -- {* 
   184   \begin{minipage}{0.9\textwidth}
   190   \begin{minipage}{0.9\textwidth}
   185   In accordance with the definition of @{text "holding wq th cs"}, 
   191   In accordance with the definition of @{text "holding wq th cs"}, a thread
   186   a thread @{text "th"} is considered waiting for @{text "cs"} if 
   192   @{text "th"} is considered waiting for @{text "cs"} if it is in the {\em
   187   it is in the {\em waiting queue} of critical resource @{text "cs"}, but not at the head.
   193   waiting queue} of critical resource @{text "cs"}, but not at the head.
   188   This is reflected in the definition of @{text "waiting wq th cs"} as follows:
   194   This is reflected in the definition of @{text "waiting wq th cs"} as
   189   \end{minipage}
   195   follows:
   190   *}
   196   \end{minipage}
   191   cs_waiting_def: 
   197   *}
   192   "waiting wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread \<noteq> hd (wq cs))"
   198 
       
   199   cs_waiting_raw: 
       
   200   "waiting_raw wq thread cs \<equiv> (thread \<in> set (wq cs) \<and> thread \<noteq> hd (wq cs))"
       
   201 
       
   202 definition
   193   -- {* 
   203   -- {* 
   194   \begin{minipage}{0.9\textwidth}
   204   \begin{minipage}{0.9\textwidth}
   195   @{text "RAG wq"} generates RAG (a binary relations on @{text "node"})
   205   @{text "RAG wq"} generates RAG (a binary relations on @{text "node"}) out
   196   out of waiting queues of the system (represented by the @{text "wq"} argument):
   206   of waiting queues of the system (represented by the @{text "wq"}
   197   \end{minipage}
   207   argument): \end{minipage}
   198   *}
   208   *}
   199   cs_RAG_def: 
   209 
   200   "RAG (wq::cs \<Rightarrow> thread list) \<equiv>
   210   cs_RAG_raw: 
   201       {(Th th, Cs cs) | th cs. waiting wq th cs} \<union> {(Cs cs, Th th) | cs th. holding wq th cs}"
   211   "RAG_raw (wq::cs \<Rightarrow> thread list) \<equiv>
       
   212       {(Th th, Cs cs) | th cs. waiting_raw wq th cs} \<union> {(Cs cs, Th th) | cs th. holding_raw wq th cs}"
       
   213 
       
   214 definition
   202   -- {* 
   215   -- {* 
   203   \begin{minipage}{0.9\textwidth}
   216   \begin{minipage}{0.9\textwidth}
   204   The following @{text "dependants wq th"} represents the set of threads which are RAGing on
   217   The following @{text "dependants wq th"} represents the set of threads
   205   thread @{text "th"} in Resource Allocation Graph @{text "RAG wq"}. 
   218   which are RAGing on thread @{text "th"} in Resource Allocation Graph
   206   Here, "RAGing" means waiting directly or indirectly on the critical resource. 
   219   @{text "RAG wq"}. Here, "RAGing" means waiting directly or indirectly on
   207   \end{minipage}
   220   the critical resource. 
   208   *}
   221   \end{minipage}
       
   222   *}
       
   223 
   209   cs_dependants_def: 
   224   cs_dependants_def: 
   210   "dependants (wq::cs \<Rightarrow> thread list) th \<equiv> {th' . (Th th', Th th) \<in> (RAG wq)^+}"
   225   "dependants_raw (wq::cs \<Rightarrow> thread list) th \<equiv> {th' . (Th th', Th th) \<in> (RAG_raw wq)^+}"
   211 
   226 
   212 
   227 text {* 
   213 text {* \noindent 
   228   \noindent The following @{text "cpreced s th"} gives the {\em current
   214   The following
   229   precedence} of thread @{text "th"} under state @{text "s"}. The definition
   215   @{text "cpreced s th"} gives the {\em current precedence} of thread @{text "th"} under
   230   of @{text "cpreced"} reflects the basic idea of Priority Inheritance that
   216   state @{text "s"}. The definition of @{text "cpreced"} reflects the basic idea of 
   231   the {\em current precedence} of a thread is the precedence inherited from
   217   Priority Inheritance that the {\em current precedence} of a thread is the precedence 
   232   the maximum of all its dependants, i.e. the threads which are waiting
   218   inherited from the maximum of all its dependants, i.e. the threads which are waiting 
   233   directly or indirectly waiting for some resources from it. If no such
   219   directly or indirectly waiting for some resources from it. If no such thread exits, 
   234   thread exits, @{text "th"}'s {\em current precedence} equals its original
   220   @{text "th"}'s {\em current precedence} equals its original precedence, i.e. 
   235   precedence, i.e. @{text "preced th s"}. 
   221   @{text "preced th s"}.
   236 *}
   222   *}
       
   223 
   237 
   224 definition cpreced :: "(cs \<Rightarrow> thread list) \<Rightarrow> state \<Rightarrow> thread \<Rightarrow> precedence"
   238 definition cpreced :: "(cs \<Rightarrow> thread list) \<Rightarrow> state \<Rightarrow> thread \<Rightarrow> precedence"
   225   where "cpreced wq s = (\<lambda>th. Max ((\<lambda>th'. preced th' s) ` ({th} \<union> dependants wq th)))"
   239   where "cpreced wq s = (\<lambda>th. Max ((\<lambda>th'. preced th' s) ` ({th} \<union> dependants_raw wq th)))"
   226 
   240 
   227 text {*
   241 text {*
   228   Notice that the current precedence (@{text "cpreced"}) of one thread @{text "th"} can be boosted 
   242   Notice that the current precedence (@{text "cpreced"}) of one thread
   229   (becoming larger than its own precedence) by those threads in 
   243   @{text "th"} can be boosted (becoming larger than its own precedence) by
   230   the @{text "dependants wq th"}-set. If one thread get boosted, we say 
   244   those threads in the @{text "dependants wq th"}-set. If one thread get
   231   it inherits the priority (or, more precisely, the precedence) of 
   245   boosted, we say it inherits the priority (or, more precisely, the
   232   its dependants. This is how the word "Inheritance" in 
   246   precedence) of its dependants. This is how the word "Inheritance" in
   233   Priority Inheritance Protocol comes.
   247   Priority Inheritance Protocol comes.
   234 *}
   248 *}
   235 
   249 
   236 (*<*)
   250 (*<*)
   237 lemma 
   251 lemma 
   238   cpreced_def2:
   252   cpreced_def2:
   239   "cpreced wq s th \<equiv> Max ({preced th s} \<union> {preced th' s | th'. th' \<in> dependants wq th})"
   253   "cpreced wq s th \<equiv> Max ({preced th s} \<union> {preced th' s | th'. th' \<in> dependants_raw wq th})"
   240   unfolding cpreced_def image_def
   254   unfolding cpreced_def image_def
   241   apply(rule eq_reflection)
   255   apply(rule eq_reflection)
   242   apply(rule_tac f="Max" in arg_cong)
   256   apply(rule_tac f="Max" in arg_cong)
   243   by (auto)
   257   by (auto)
   244 (*>*)
   258 (*>*)
   245 
   259 
   246 
   260 
   247 text {* \noindent
   261 text {* 
   248   Assuming @{text "qs"} be the waiting queue of a critical resource, 
   262 
   249   the following abbreviation "release qs" is the waiting queue after the thread 
   263   \noindent Assuming @{text "qs"} be the waiting queue of a critical
   250   holding the resource (which is thread at the head of @{text "qs"}) released
   264   resource, the following abbreviation "release qs" is the waiting queue
   251   the resource:
   265   after the thread holding the resource (which is thread at the head of
   252 *}
   266   @{text "qs"}) released the resource: 
       
   267 *}
       
   268 
   253 abbreviation
   269 abbreviation
   254   "release qs \<equiv> case qs of
   270   "release qs \<equiv> case qs of
   255              [] => [] 
   271              [] => [] 
   256           |  (_#qs') => (SOME q. distinct q \<and> set q = set qs')"
   272           |  (_#qs') => (SOME q. distinct q \<and> set q = set qs')"
   257 text {* \noindent
   273 
   258   It can be seen from the definition that the thread at the head of @{text "qs"} is removed
   274 text {* 
   259   from the return value, and the value @{term "q"} is an reordering of @{text "qs'"}, the 
   275   \noindent It can be seen from the definition that the thread at the head
   260   tail of @{text "qs"}. Through this reordering, one of the waiting threads (those in @{text "qs'"} }
   276   of @{text "qs"} is removed from the return value, and the value @{term
   261   is chosen nondeterministically to be the head of the new queue @{text "q"}. 
   277   "q"} is an reordering of @{text "qs'"}, the tail of @{text "qs"}. Through
   262   Therefore, this thread is the one who takes over the resource. This is a little better different 
   278   this reordering, one of the waiting threads (those in @{text "qs'"} } is
   263   from common sense that the thread who comes the earliest should take over.  
   279   chosen nondeterministically to be the head of the new queue @{text "q"}.
   264   The intention of this definition is to show that the choice of which thread to take over the 
   280   Therefore, this thread is the one who takes over the resource. This is a
   265   release resource does not affect the correctness of the PIP protocol. 
   281   little better different from common sense that the thread who comes the
   266 *}
   282   earliest should take over. The intention of this definition is to show
   267 
   283   that the choice of which thread to take over the release resource does not
   268 text {*
   284   affect the correctness of the PIP protocol. 
   269   The data structure used by the operating system for scheduling is referred to as 
   285 *}
   270   {\em schedule state}. It is represented as a record consisting of 
   286 
   271   a function assigning waiting queue to resources 
   287 text {*
   272   (to be used as the @{text "wq"} argument in @{text "holding"}, @{text "waiting"} 
   288   The data structure used by the operating system for scheduling is referred
   273   and  @{text "RAG"}, etc) and a function assigning precedence to threads:
   289   to as {\em schedule state}. It is represented as a record consisting of a
       
   290   function assigning waiting queue to resources (to be used as the @{text
       
   291   "wq"} argument in @{text "holding"}, @{text "waiting"} and @{text "RAG"},
       
   292   etc) and a function assigning precedence to threads:
   274   *}
   293   *}
   275 
   294 
   276 record schedule_state = 
   295 record schedule_state = 
   277     wq_fun :: "cs \<Rightarrow> thread list" -- {* The function assigning waiting queue. *}
   296     wq_fun :: "cs \<Rightarrow> thread list" -- {* The function assigning waiting queue. *}
   278     cprec_fun :: "thread \<Rightarrow> precedence" -- {* The function assigning precedence. *}
   297     cprec_fun :: "thread \<Rightarrow> precedence" -- {* The function assigning precedence. *}
   279 
   298 
   280 text {* \noindent
   299 text {* 
   281   The following two abbreviations (@{text "all_unlocked"} and @{text "initial_cprec"}) 
   300   \noindent The following two abbreviations (@{text "all_unlocked"} and
   282   are used to set the initial values of the @{text "wq_fun"} @{text "cprec_fun"} fields 
   301   @{text "initial_cprec"}) are used to set the initial values of the @{text
   283   respectively of the @{text "schedule_state"} record by the following function @{text "sch"},
   302   "wq_fun"} @{text "cprec_fun"} fields respectively of the @{text
   284   which is used to calculate the system's {\em schedule state}.
   303   "schedule_state"} record by the following function @{text "sch"}, which is
   285 
   304   used to calculate the system's {\em schedule state}.
   286   Since there is no thread at the very beginning to make request, all critical resources 
   305 
   287   are free (or unlocked). This status is represented by the abbreviation
   306   Since there is no thread at the very beginning to make request, all
   288   @{text "all_unlocked"}. 
   307   critical resources are free (or unlocked). This status is represented by
   289   *}
   308   the abbreviation @{text "all_unlocked"}.
       
   309 *}
       
   310 
   290 abbreviation
   311 abbreviation
   291   "all_unlocked \<equiv> \<lambda>_::cs. ([]::thread list)"
   312   "all_unlocked \<equiv> \<lambda>_::cs. ([]::thread list)"
   292 
   313 
   293 
   314 
   294 text {* \noindent
   315 text {* \noindent
   369           (|wq_fun = new_wq, cprec_fun = cpreced new_wq (V th cs # s)|))"
   390           (|wq_fun = new_wq, cprec_fun = cpreced new_wq (V th cs # s)|))"
   370 
   391 
   371 lemma cpreced_initial: 
   392 lemma cpreced_initial: 
   372   "cpreced (\<lambda> cs. []) [] = (\<lambda>_. (Prc 0 0))"
   393   "cpreced (\<lambda> cs. []) [] = (\<lambda>_. (Prc 0 0))"
   373 apply(simp add: cpreced_def)
   394 apply(simp add: cpreced_def)
   374 apply(simp add: cs_dependants_def cs_RAG_def cs_waiting_def cs_holding_def)
   395 apply(simp add: cs_dependants_def cs_RAG_raw cs_waiting_raw cs_holding_raw)
   375 apply(simp add: preced_def)
   396 apply(simp add: preced_def)
   376 done
   397 done
   377 
   398 
   378 lemma sch_old_def:
   399 lemma sch_old_def:
   379   "schs (e#s) = (let ps = schs s in 
   400   "schs (e#s) = (let ps = schs s in 
   411   @{text "dependants"} still have the 
   432   @{text "dependants"} still have the 
   412   same meaning, but redefined so that they no longer RAG on the 
   433   same meaning, but redefined so that they no longer RAG on the 
   413   fictitious {\em waiting queue function}
   434   fictitious {\em waiting queue function}
   414   @{text "wq"}, but on system state @{text "s"}.
   435   @{text "wq"}, but on system state @{text "s"}.
   415   *}
   436   *}
   416 defs (overloaded) 
   437 
       
   438 
       
   439 definition 
   417   s_holding_abv: 
   440   s_holding_abv: 
   418   "holding (s::state) \<equiv> holding (wq_fun (schs s))"
   441   "holding (s::state) \<equiv> holding_raw (wq_fun (schs s))"
       
   442 
       
   443 definition
   419   s_waiting_abv: 
   444   s_waiting_abv: 
   420   "waiting (s::state) \<equiv> waiting (wq_fun (schs s))"
   445   "waiting (s::state) \<equiv> waiting_raw (wq_fun (schs s))"
       
   446 
       
   447 definition
   421   s_RAG_abv: 
   448   s_RAG_abv: 
   422   "RAG (s::state) \<equiv> RAG (wq_fun (schs s))"
   449   "RAG (s::state) \<equiv> RAG_raw (wq_fun (schs s))"
       
   450   
       
   451 definition
   423   s_dependants_abv: 
   452   s_dependants_abv: 
   424   "dependants (s::state) \<equiv> dependants (wq_fun (schs s))"
   453   "dependants (s::state) \<equiv> dependants_raw (wq_fun (schs s))"
   425 
   454 
   426 
   455 
   427 text {* 
   456 text {* 
   428   The following lemma can be proved easily, and the meaning is obvious.
   457   The following lemma can be proved easily, and the meaning is obvious.
   429   *}
   458   *}
       
   459 
   430 lemma
   460 lemma
   431   s_holding_def: 
   461   s_holding_def: 
   432   "holding (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th = hd (wq_fun (schs s) cs))"
   462   "holding (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th = hd (wq_fun (schs s) cs))"
   433   by (auto simp:s_holding_abv wq_def cs_holding_def)
   463   by (auto simp:s_holding_abv wq_def cs_holding_raw)
   434 
   464 
   435 lemma s_waiting_def: 
   465 lemma s_waiting_def: 
   436   "waiting (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th \<noteq> hd (wq_fun (schs s) cs))"
   466   "waiting (s::state) th cs \<equiv> (th \<in> set (wq_fun (schs s) cs) \<and> th \<noteq> hd (wq_fun (schs s) cs))"
   437   by (auto simp:s_waiting_abv wq_def cs_waiting_def)
   467   by (auto simp:s_waiting_abv wq_def cs_waiting_raw)
   438 
   468 
   439 lemma s_RAG_def: 
   469 lemma s_RAG_def: 
   440   "RAG (s::state) =
   470   "RAG (s::state) =
   441     {(Th th, Cs cs) | th cs. waiting (wq s) th cs} \<union> {(Cs cs, Th th) | cs th. holding (wq s) th cs}"
   471     {(Th th, Cs cs) | th cs. waiting_raw (wq s) th cs} \<union> {(Cs cs, Th th) | cs th. holding_raw (wq s) th cs}"
   442   by (auto simp:s_RAG_abv wq_def cs_RAG_def)
   472   by (auto simp:s_RAG_abv wq_def cs_RAG_raw)
   443 
   473 
   444 lemma
   474 lemma
   445   s_dependants_def: 
   475   s_dependants_def: 
   446   "dependants (s::state) th \<equiv> {th' . (Th th', Th th) \<in> (RAG (wq s))^+}"
   476   "dependants (s::state) th \<equiv> {th' . (Th th', Th th) \<in> (RAG_raw (wq s))^+}"
   447   by (auto simp:s_dependants_abv wq_def cs_dependants_def)
   477   by (auto simp:s_dependants_abv wq_def cs_dependants_def)
   448 
   478 
   449 text {*
   479 text {*
   450   The following function @{text "readys"} calculates the set of ready threads. A thread is {\em ready} 
   480   The following function @{text "readys"} calculates the set of ready
   451   for running if it is a live thread and it is not waiting for any critical resource.
   481   threads. A thread is {\em ready} for running if it is a live thread and it
   452   *}
   482   is not waiting for any critical resource.
       
   483   *}
       
   484 
   453 definition readys :: "state \<Rightarrow> thread set"
   485 definition readys :: "state \<Rightarrow> thread set"
   454   where "readys s \<equiv> {th . th \<in> threads s \<and> (\<forall> cs. \<not> waiting s th cs)}"
   486   where "readys s \<equiv> {th . th \<in> threads s \<and> (\<forall> cs. \<not> waiting s th cs)}"
   455 
   487 
   456 text {* \noindent
   488 text {* 
   457   The following function @{text "runing"} calculates the set of running thread, which is the ready 
   489   \noindent The following function @{text "runing"} calculates the set of
   458   thread with the highest precedence.  
   490   running thread, which is the ready thread with the highest precedence.
   459   *}
   491   *}
       
   492 
   460 definition runing :: "state \<Rightarrow> thread set"
   493 definition runing :: "state \<Rightarrow> thread set"
   461   where "runing s \<equiv> {th . th \<in> readys s \<and> cp s th = Max ((cp s) ` (readys s))}"
   494   where "runing s \<equiv> {th . th \<in> readys s \<and> cp s th = Max ((cp s) ` (readys s))}"
   462 
   495 
   463 text {* \noindent
   496 text {* 
   464   Notice that the definition of @{text "running"} reflects the preemptive scheduling strategy,  
   497   \noindent Notice that the definition of @{text "running"} reflects the
   465   because, if the @{text "running"}-thread (the one in @{text "runing"} set) 
   498   preemptive scheduling strategy, because, if the @{text "running"}-thread
   466   lowered its precedence by resetting its own priority to a lower
   499   (the one in @{text "runing"} set) lowered its precedence by resetting its
   467   one, it will lose its status of being the max in @{text "ready"}-set and be superseded.
   500   own priority to a lower one, it will lose its status of being the max in
   468 *}
   501   @{text "ready"}-set and be superseded. 
   469 
   502 *}
   470 text {* \noindent
   503 
   471   The following function @{text "holdents s th"} returns the set of resources held by thread 
   504 text {* 
   472   @{text "th"} in state @{text "s"}.
   505   \noindent The following function @{text "holdents s th"} returns the set
   473   *}
   506   of resources held by thread @{text "th"} in state @{text "s"}. *}
   474 definition holdents :: "state \<Rightarrow> thread \<Rightarrow> cs set"
   507 
       
   508 
       
   509 definition holdents :: "state \<Rightarrow> thread \<Rightarrow> cs set" 
   475   where "holdents s th \<equiv> {cs . holding s th cs}"
   510   where "holdents s th \<equiv> {cs . holding s th cs}"
   476 
   511 
   477 lemma holdents_test: 
   512 lemma holdents_test: 
   478   "holdents s th = {cs . (Cs cs, Th th) \<in> RAG s}"
   513   "holdents s th = {cs . (Cs cs, Th th) \<in> RAG s}"
   479 unfolding holdents_def
   514 unfolding holdents_def
   657   names @{term "wRAG"} and @{term "hRAG"}.
   692   names @{term "wRAG"} and @{term "hRAG"}.
   658  *}
   693  *}
   659 definition "tRAG s = wRAG s O hRAG s"
   694 definition "tRAG s = wRAG s O hRAG s"
   660 
   695 
   661 text {* The following lemma splits @{term "RAG"} graph into the above two sub-graphs. *}
   696 text {* The following lemma splits @{term "RAG"} graph into the above two sub-graphs. *}
       
   697 
   662 lemma RAG_split: "RAG s = (wRAG s \<union> hRAG s)"
   698 lemma RAG_split: "RAG s = (wRAG s \<union> hRAG s)"
   663   by (unfold s_RAG_abv wRAG_def hRAG_def s_waiting_abv 
   699   by (unfold s_RAG_abv wRAG_def hRAG_def s_waiting_abv 
   664              s_holding_abv cs_RAG_def, auto)
   700              s_holding_abv cs_RAG_raw, auto)
   665 
   701 
   666 lemma tRAG_alt_def: 
   702 lemma tRAG_alt_def: 
   667   "tRAG s = {(Th th1, Th th2) | th1 th2. 
   703   "tRAG s = {(Th th1, Th th2) | th1 th2. 
   668                   \<exists> cs. (Th th1, Cs cs) \<in> RAG s \<and> (Cs cs, Th th2) \<in> RAG s}"
   704                   \<exists> cs. (Th th1, Cs cs) \<in> RAG s \<and> (Cs cs, Th th2) \<in> RAG s}"
   669  by (auto simp:tRAG_def RAG_split wRAG_def hRAG_def)
   705  by (auto simp:tRAG_def RAG_split wRAG_def hRAG_def)