00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_HXX
00019 # define VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_HXX
00020
00021 # include <utility>
00022 # include <list>
00023
00024 # include <vaucanson/algebra/implementation/series/series.hh>
00025 # include <vaucanson/algebra/implementation/series/rat/exp.hh>
00026 # include <vaucanson/algebra/implementation/series/rat/random_visitor.hh>
00027 # include <vaucanson/misc/usual_macros.hh>
00028
00029 # include <vaucanson/algebra/implementation/series/krat_exp_is_finite_app.hxx>
00030 # include <vaucanson/algebra/implementation/series/krat_exp_support.hxx>
00031 # include <vaucanson/algebra/implementation/series/krat_exp_transpose.hxx>
00032
00033 # include <vaucanson/algorithms/eval.hh>
00034 # include <vaucanson/algorithms/standard_of.hh>
00035
00036 # include <vaucanson/algebra/implementation/series/polynoms.hh>
00037 # include <vaucanson/automata/concept/automata.hh>
00038
00039 # include <vaucanson/misc/contract.hh>
00040
00041 namespace vcsn
00042 {
00043 namespace algebra
00044 {
00059 template<typename W, typename M, typename Tm, typename Tw>
00060 bool op_contains(const algebra::Series<W, M>&, const rat::exp<Tm, Tw>&)
00061 {
00062 pure_service_call ("default version of op_contains(Series<W,M>, exp<Tm,Tw>)");
00063 return true;
00064 }
00065
00066 template<typename W, typename M, typename Tm, typename Tw>
00067 bool op_is_finite_app(const algebra::Series<W, M>&,
00068 const rat::exp<Tm, Tw>& m)
00069 {
00070 vcsn::IsFiniteAppMatcher<
00071 algebra::Series<W, M>,
00072 vcsn::rat::exp<Tm, Tw>,
00073 algebra::DispatchFunction<vcsn::rat::exp<Tm, Tw> >
00074 > matcher;
00075 return matcher.match(m);
00076 }
00077
00078 template<typename W, typename M, typename Tm, typename Tw>
00079 typename algebra::series_traits<rat::exp<Tm, Tw> >::support_t
00080 op_support(const algebra::Series<W, M>& s, const rat::exp<Tm, Tw>& m)
00081 {
00082 vcsn::SupportMatcher<
00083 algebra::Series<W, M>, rat::exp<Tm, Tw>,
00084 algebra::DispatchFunction<rat::exp<Tm, Tw> >
00085 > matcher(s);
00086 matcher.match(m);
00087 return matcher.get();
00088 }
00089
00090 template <typename W, typename M, typename Tm, typename Tw>
00091 Tm op_choose_from_supp(const algebra::Series<W, M>&,
00092 const rat::exp<Tm, Tw>& m)
00093 {
00094 rat::RandomVisitor<Tm, Tw> v;
00095 m.accept(v);
00096 return v.get();
00097 }
00098
00099 template<typename W, typename M, typename Tm, typename Tw>
00100 const rat::exp<Tm, Tw>& identity_value(SELECTOR2(algebra::Series<W, M>),
00101 SELECTOR2(rat::exp<Tm, Tw>))
00102 {
00103 static const rat::exp<Tm, Tw> instance = rat::exp<Tm, Tw>::one();
00104 return instance;
00105 }
00106
00107 template<typename W, typename M, typename Tm, typename Tw>
00108 bool show_identity_value(SELECTOR2(algebra::Series<W, M>),
00109 SELECTOR2(rat::exp<Tm, Tw>))
00110 {
00111 return true;
00112 }
00113
00114 template<typename W, typename M, typename Tm, typename Tw>
00115 const rat::exp<Tm, Tw>& zero_value(SELECTOR2(algebra::Series<W, M>),
00116 SELECTOR2(rat::exp<Tm, Tw>))
00117 {
00118 static const rat::exp<Tm, Tw> instance = rat::exp<Tm, Tw>::zero();
00119 return instance;
00120 }
00121
00122 template <typename W, typename M, typename Tm, typename Tw>
00123 void op_in_transpose(const algebra::Series<W, M>& s,
00124 rat::exp<Tm, Tw>& exp)
00125 {
00126 Element<algebra::Series<W, M>,
00127 rat::exp<Tm, Tw> > elt(s, exp);
00128
00129 vcsn::algebra::KRatExpTranspose<
00130 algebra::Series<W, M>,
00131 rat::exp<Tm, Tw>,
00132 algebra::DispatchFunction<vcsn::rat::exp<Tm, Tw> >
00133 > matcher(elt);
00134
00135 elt = matcher.match(exp);
00136 exp = elt.value();
00137 }
00138
00139 template<typename W, typename M, typename Tm, typename Tw>
00140 void op_in_add(const algebra::Series<W, M>&,
00141 rat::exp<Tm, Tw>& dst,
00142 const rat::exp<Tm, Tw>& arg)
00143 {
00144
00145 if (arg.base()->what() == rat::Node<Tm, Tw>::zero)
00146 return ;
00147
00148
00149 if (dst.base()->what() == rat::Node<Tm, Tw>::zero)
00150 {
00151 delete dst.base();
00152 dst.base() = arg.base()->clone();
00153 return;
00154 }
00155
00156 dst.base() = new rat::Sum<Tm, Tw>(dst.base(), arg.base()->clone());
00157 }
00158
00159 template<typename W, typename M, typename Tm, typename Tw>
00160 rat::exp<Tm, Tw> op_add(const algebra::Series<W, M>& s,
00161 const rat::exp<Tm, Tw>& a,
00162 const rat::exp<Tm, Tw>& b)
00163 {
00164 rat::exp<Tm, Tw> ret(a);
00165 op_in_add(s, ret, b);
00166 return ret;
00167 }
00168
00169 template<typename W, typename M, typename Tm, typename Tw>
00170 void op_in_mul(const algebra::Series<W, M>& s,
00171 rat::exp<Tm, Tw>& dst,
00172 const rat::exp<Tm, Tw>& arg)
00173 {
00174 typedef rat::Node<Tm, Tw> node_t;
00175 typedef typename rat::Node<Tm, Tw>::type type;
00176 typedef rat::One<Tm, Tw> n_one_t;
00177 typedef rat::Constant<Tm, Tw> n_const_t;
00178 typedef rat::Zero<Tm, Tw> n_zero_t;
00179 typedef rat::Star<Tm, Tw> n_star_t;
00180 typedef rat::LeftWeighted<Tm, Tw> n_lweight_t;
00181 typedef rat::RightWeighted<Tm, Tw> n_rweight_t;
00182 typedef rat::Sum<Tm, Tw> n_sum_t;
00183 typedef rat::Product<Tm, Tw> n_prod_t;
00184
00185 type this_type = dst.base()->what();
00186 type arg_type = arg.base()->what();
00187
00188
00189 if (this_type == node_t::zero)
00190 return;
00191
00192
00193 if (arg_type == node_t::zero)
00194 {
00195 delete dst.base();
00196 dst.base() = new n_zero_t;
00197 return;
00198 }
00199
00200
00201 if (this_type == node_t::one)
00202 {
00203 delete dst.base();
00204 dst.base() = arg.base()->clone();
00205 return;
00206 }
00207
00208
00209 if (arg_type == node_t::one)
00210 {
00211 return;
00212 }
00213
00214
00215 if (arg_type == node_t::lweight)
00216 {
00217 n_lweight_t *p = dynamic_cast<n_lweight_t*>(arg.base());
00218 if (p->child_->what() == node_t::one)
00219 {
00220 op_in_mul(s, s.semiring(), dst, p->weight_);
00221 return;
00222 }
00223 }
00224
00225
00226 if (this_type == node_t::lweight)
00227 {
00228 n_lweight_t *p = dynamic_cast<n_lweight_t*>(dst.base());
00229 if (p->child_->what() == node_t::one)
00230 {
00231 dst = op_mul(s.semiring(), s, p->weight_, arg);
00232 return;
00233 }
00234 }
00235
00236
00237 dst.base() = new n_prod_t(dst.base(), arg.base()->clone());
00238 return;
00239 }
00240
00241 template<typename W, typename M, typename Tm, typename Tw>
00242 rat::exp<Tm, Tw> op_mul(const algebra::Series<W, M>& s,
00243 const rat::exp<Tm, Tw>& a,
00244 const rat::exp<Tm, Tw>& b)
00245 {
00246 rat::exp<Tm, Tw> ret(a);
00247 op_in_mul(s, ret, b);
00248 return ret;
00249 }
00250
00251 template <typename W, typename M, typename Tm, typename Tw, typename St>
00252 St&
00253 op_rout(const algebra::Series<W, M>& s,
00254 St& st,
00255 const rat::exp<Tm, Tw>& e)
00256 {
00257 rat::DumpVisitor<Tm, Tw, W, M> v (st, s.monoid(), s.representation());
00258 e.accept(v);
00259 return st;
00260 }
00261
00262
00263
00264
00265
00266 template<typename Tm, typename Tw, typename M, typename W>
00267 rat::exp<Tm, Tw> op_convert(SELECTOR2(algebra::Series<M, W>),
00268 SELECTOR2(rat::exp<Tm, Tw>),
00269 const Tm& m_value)
00270 {
00271 return new rat::Constant<Tm, Tw>(m_value);
00272 }
00273
00274 template<typename Tm, typename Tw, typename M, typename W>
00275 rat::exp<Tm, Tw> op_convert(SELECTOR2(algebra::Series<M, W>),
00276 SELECTOR2(rat::exp<Tm, Tw>),
00277 char m_value)
00278 {
00279 const char str[] = {m_value, '\0'};
00280 return new rat::Constant<Tm, Tw>(str);
00281 }
00282
00283 template<typename Tm, typename Tw, typename W, typename M, typename oTm>
00284 rat::exp<Tm, Tw> op_convert(SELECTOR2(algebra::Series<W, M>) s,
00285 SELECTOR2(rat::exp<Tm, Tw>),
00286 SELECTOR(M),
00287 const oTm& m_value)
00288 {
00289 if (m_value == identity_value(SELECT(M), SELECT(oTm)))
00290 return rat::exp<Tm, Tw>::one();
00291
00292 return rat::exp<Tm, Tw>::constant(op_convert(s.monoid(), SELECT(Tm),
00293 m_value));
00294 }
00295
00296 template<typename Tm, typename Tw, typename W, typename M, typename oTw>
00297 rat::exp<Tm, Tw> op_convert(SELECTOR2(algebra::Series<W, M>),
00298 SELECTOR2(rat::exp<Tm, Tw>),
00299 SELECTOR(W),
00300 const oTw& w_value)
00301 {
00302 if (w_value == identity_value(SELECT(W), SELECT(oTw)))
00303 return rat::exp<Tm, Tw>::one();
00304 if (w_value == zero_value(SELECT(W), SELECT(oTw)))
00305 return rat::exp<Tm, Tw>::zero();
00306 rat::exp<Tm, Tw> ret = rat::exp<Tm, Tw>::one();
00307 ret.base() = new rat::LeftWeighted<Tm, Tw>
00308 (op_convert(SELECT(W), SELECT(Tw),
00309 w_value), ret.base());
00310 return ret;
00311 }
00312
00313 template <typename W, typename M, typename Tm, typename Tw, typename oTm>
00314 void op_assign(SELECTOR2(algebra::Series<W, M>) s,
00315 SELECTOR(M),
00316 rat::exp<Tm, Tw>& dst,
00317 const oTm& src)
00318 {
00319 dst = op_convert(s,
00320 SELECT2(rat::exp<Tm, Tw>),
00321 SELECT(M), src);
00322 }
00323
00324 template <typename W, typename M, typename Tm, typename Tw, typename oTw>
00325 void op_assign(SELECTOR2(algebra::Series<W, M>) s,
00326 SELECTOR(W),
00327 rat::exp<Tm, Tw>& dst,
00328 const oTw& src)
00329 {
00330 dst = op_convert(s,
00331 SELECT2(rat::exp<Tm, Tw>),
00332 SELECT(W), src);
00333 }
00334
00335
00336
00337
00338
00339 template<typename W, typename M, typename Tm, typename Tw>
00340 bool op_starable(const algebra::Series<W, M>&,
00341 const rat::exp<Tm, Tw>&)
00342 {
00343 return true;
00344 }
00345
00346 template<typename W, typename M, typename Tm, typename Tw>
00347 void op_in_star(const algebra::Series<W, M>&,
00348 rat::exp<Tm, Tw>& dst)
00349 {
00350
00351 if (dst.base()->what() == rat::Node<Tm, Tw>::zero)
00352 dst = rat::exp<Tm, Tw>::one();
00353 else
00354 dst.base() = new rat::Star<Tm, Tw>(dst.base());
00355 }
00356
00357 template<typename W, typename M, typename Tm, typename Tw>
00358 rat::exp<Tm, Tw>
00359 op_star(const algebra::Series<W, M>& s,
00360 const rat::exp<Tm, Tw>& src)
00361 {
00362 rat::exp<Tm, Tw> ret(src);
00363 op_in_star(s, ret);
00364 return ret;
00365 }
00366
00367
00368
00369
00370
00371 template<typename W, typename M, typename Tm, typename Tw, typename oTm>
00372 void op_in_add(const algebra::Series<W, M>& s,
00373 const M& monoid,
00374 rat::exp<Tm, Tw>& dst,
00375 const oTm& src)
00376 {
00377 op_in_add(s, dst, op_convert(s,
00378 SELECT2(rat::exp<Tm, Tw>),
00379 SELECT(M),
00380 src));
00381 }
00382
00383 template<typename W, typename M, typename Tm, typename Tw, typename oTm>
00384 rat::exp<Tm, Tw> op_add(const algebra::Series<W, M>& s,
00385 const M& monoid,
00386 const rat::exp<Tm, Tw>& a,
00387 const oTm& b)
00388 {
00389 rat::exp<Tm, Tw> ret(a);
00390 op_in_add(s, monoid, ret, b);
00391 return ret;
00392 }
00393
00394 template<typename M, typename W, typename oTm, typename Tm, typename Tw>
00395 rat::exp<Tm, Tw> op_add(const M& monoid,
00396 const algebra::Series<W, M>& s,
00397 const oTm& a,
00398 const rat::exp<Tm, Tw>& b)
00399 {
00400 rat::exp<Tm, Tw> ret(b);
00401 op_in_add(s, monoid, ret, a);
00402 return ret;
00403 }
00404
00405
00406
00407
00408
00409 template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00410 void op_in_add(const algebra::Series<W, M>& s,
00411 const W& semiring,
00412 rat::exp<Tm, Tw>& dst,
00413 const oTw& src)
00414 {
00415 precondition(& s.semiring() == & semiring);
00416 op_in_add(s, dst, op_convert(s,
00417 SELECT2(rat::exp<Tm, Tw>),
00418 SELECT(W),
00419 src));
00420 }
00421
00422 template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00423 rat::exp<Tm, Tw> op_add(const algebra::Series<W, M>& s,
00424 const W& semiring,
00425 const rat::exp<Tm, Tw>& a,
00426 const oTw& b)
00427 {
00428 rat::exp<Tm, Tw> ret(a);
00429 op_in_add(s, semiring, ret, b);
00430 return ret;
00431 }
00432
00433 template<typename W, typename M, typename oTw, typename Tm, typename Tw>
00434 rat::exp<Tm, Tw> op_add(const W& semiring,
00435 const algebra::Series<W, M>& s,
00436 const oTw& a,
00437 const rat::exp<Tm, Tw>& b)
00438 {
00439 rat::exp<Tm, Tw> ret(b);
00440 op_in_add(s, semiring, ret, a);
00441 return ret;
00442 }
00443
00444
00445
00446
00447
00448 template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00449 void op_in_mul(const algebra::Series<W, M>& s,
00450 const W& semiring,
00451 rat::exp<Tm, Tw>& ret,
00452 const oTw& w)
00453 {
00454 precondition(& s.semiring() == & semiring);
00455 (void) s; (void) semiring;
00456
00457 typedef rat::Node<Tm, Tw> node_t;
00458 typedef typename rat::Node<Tm, Tw>::type type;
00459 typedef rat::One<Tm, Tw> n_one_t;
00460 typedef rat::Constant<Tm, Tw> n_const_t;
00461 typedef rat::Zero<Tm, Tw> n_zero_t;
00462 typedef rat::Star<Tm, Tw> n_star_t;
00463 typedef rat::LeftWeighted<Tm, Tw> n_lweight_t;
00464 typedef rat::RightWeighted<Tm, Tw> n_rweight_t;
00465 typedef rat::Sum<Tm, Tw> n_sum_t;
00466 typedef rat::Product<Tm, Tw> n_prod_t;
00467
00468 type this_type = ret.base()->what();
00469
00470
00471 if (this_type == node_t::zero)
00472 return;
00473
00474
00475 if (w == identity_value(SELECT(W), SELECT(oTw)))
00476 return;
00477
00478
00479 if (w == zero_value(SELECT(W), SELECT(oTw)))
00480 {
00481 delete ret.base();
00482 ret.base() = new n_zero_t;
00483 return;
00484 }
00485
00486
00487 if (this_type == node_t::one)
00488 {
00489 ret.base() = new n_lweight_t
00490 (op_convert(SELECT(W), SELECT(Tw), w), ret.base());
00491 return;
00492 }
00493
00494
00495 if ((this_type == node_t::constant)
00496 && op_is_atom(s.monoid(),
00497 dynamic_cast<n_const_t*>(ret.base())->value_))
00498 {
00499 ret.base() = new n_lweight_t
00500 (op_convert(SELECT(W), SELECT(Tw), w), ret.base());
00501 return;
00502 }
00503
00504
00505 if (this_type == node_t::rweight)
00506 {
00507 op_in_mul(s.semiring(),
00508 dynamic_cast<n_rweight_t* >(ret.base())->weight_,
00509 op_convert(SELECT(W), SELECT(Tw), w));
00510 return;
00511 }
00512
00513
00514
00515
00516
00517
00518
00519 if (this_type == node_t::lweight)
00520 {
00521
00522 n_lweight_t* p = dynamic_cast<n_lweight_t*>(ret.base());
00523 if ((p->child_->what() == node_t::constant
00524 && op_is_atom(s.monoid(),
00525 dynamic_cast<n_const_t*>(p->child_)->value_))
00526 || p->child_->what() == node_t::one)
00527 {
00528 p->weight_ = op_mul (s.semiring(), p->weight_,
00529 op_convert(SELECT(W), SELECT(Tw), w));
00530 }
00531 else
00532 {
00533
00534 if (p->child_->what() == node_t::rweight)
00535 {
00536 n_rweight_t* q = dynamic_cast<n_rweight_t*>(p->child_);
00537 assert(q);
00538 q->weight_ = op_mul (s.semiring(),
00539 q->weight_,
00540 op_convert(SELECT(W), SELECT(Tw), w));
00541 }
00542 else
00543 {
00544 p->child_ =
00545 new n_rweight_t(op_convert(SELECT(W), SELECT(Tw), w),
00546 p->child_);
00547 }
00548 }
00549 return;
00550 }
00551
00552
00553 ret.base() =
00554 new n_rweight_t(op_convert(SELECT(W), SELECT(Tw), w), ret.base());
00555 return;
00556 }
00557
00558 template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00559 rat::exp<Tm, Tw> op_mul(const algebra::Series<W, M>& s,
00560 const W& semiring,
00561 const rat::exp<Tm, Tw>& a,
00562 const oTw& w)
00563 {
00564 rat::exp<Tm, Tw> ret(a);
00565 op_in_mul(s, semiring, ret, w);
00566 return ret;
00567 }
00568
00569 template<typename W, typename M, typename oTw, typename Tm, typename Tw>
00570 rat::exp<Tm, Tw> op_mul(const W& semiring,
00571 const algebra::Series<W, M>& s,
00572 const oTw& w,
00573 const rat::exp<Tm, Tw>& b)
00574 {
00575 precondition(& s.semiring() == & semiring);
00576 (void) s; (void) semiring;
00577
00578 typedef rat::Node<Tm, Tw> node_t;
00579 typedef typename rat::Node<Tm, Tw>::type type;
00580 typedef rat::One<Tm, Tw> n_one_t;
00581 typedef rat::Constant<Tm, Tw> n_const_t;
00582 typedef rat::Zero<Tm, Tw> n_zero_t;
00583 typedef rat::Star<Tm, Tw> n_star_t;
00584 typedef rat::LeftWeighted<Tm, Tw> n_lweight_t;
00585 typedef rat::RightWeighted<Tm, Tw> n_rweight_t;
00586 typedef rat::Sum<Tm, Tw> n_sum_t;
00587 typedef rat::Product<Tm, Tw> n_prod_t;
00588
00589 rat::exp<Tm, Tw> ret(b);
00590
00591 type this_type = ret.base()->what();
00592
00593
00594 if (this_type == node_t::zero)
00595 return ret;
00596
00597
00598
00599
00600 if (w == zero_value(SELECT(W), SELECT(oTw)))
00601 { return rat::exp<Tm, Tw>::zero(); }
00602
00603
00604 if (w == identity_value(SELECT(W), SELECT(oTw)))
00605 return ret;
00606
00607
00608 if (this_type == node_t::lweight)
00609 {
00610 n_lweight_t* p = dynamic_cast<n_lweight_t*>(ret.base());
00611 p->weight_ = op_mul
00612 (s.semiring(), op_convert(SELECT(W), SELECT(Tw), w), p->weight_);
00613 return ret;
00614 }
00615
00616
00617 ret.base() = new n_lweight_t(w, ret.base());
00618 return ret;
00619 }
00620
00621 template<typename W, typename M, typename Tm, typename Tw, typename oTm>
00622 Tw op_series_get(const algebra::Series<W, M>& s,
00623 const rat::exp<Tm, Tw>& p,
00624 const oTm& m)
00625 {
00626 typedef typename standard_of_traits<algebra::Series<W, M>,
00627 rat::exp<Tm, Tw> >::
00628 automaton_t automaton_t;
00629
00630 typename automaton_t::set_t automata (s);
00631 automaton_t a (automata);
00632 standard_of(a, p);
00633 return eval(a, m).value();
00634 }
00635
00636 template<typename W, typename M, typename Tm, typename Tw,
00637 typename oTm, typename oTw>
00638 void op_series_set(const algebra::Series<W, M>& s,
00639 rat::exp<Tm, Tw>& p,
00640 const oTm& m,
00641 const oTw& w)
00642 {
00643 if ((m == algebra::identity_as<oTm>::of(s.monoid())) &&
00644 (w == algebra::identity_as<oTw>::of(s.semiring())) &&
00645 (p == algebra::zero_as<rat::exp<Tm, Tw> >::of(s)))
00646 {
00647 p = algebra::identity_as<rat::exp<Tm, Tw> >::of(s).value();
00648 return ;
00649 }
00650
00651 typedef Element<algebra::Series<W, M>, rat::exp<Tm, Tw> > series_set_elt_t;
00652 typedef typename series_set_elt_t::monoid_elt_t monoid_elt_t;
00653 typedef typename monoid_elt_t::value_t monoid_elt_value_t;
00654 typedef std::list<monoid_elt_value_t> support_t;
00655
00656 rat::exp<Tm, Tw> pp = p;
00657 p = algebra::zero_as<rat::exp<Tm, Tw> >::of(s).value();
00658
00659
00660
00661 support_t supp = op_support(s, pp);
00662 oTw sw;
00663 bool exist = false;
00664 for_all_const_(support_t, e, supp)
00665 {
00666 rat::exp<Tm, Tw> ret = op_convert(s,
00667 SELECT2(rat::exp<Tm, Tw>),
00668 SELECT(M), *e);
00669 if (*e == m)
00670 {
00671 exist = true;
00672 sw = w;
00673 }
00674 else
00675 sw = op_series_get(s, pp, *e);
00676
00677 op_in_add(s, p, op_mul(s.semiring(), s, sw, ret));
00678 }
00679 if (!exist)
00680 op_in_add(s, p, op_mul(s.semiring(), s, w,
00681 op_convert(s,
00682 SELECT2(rat::exp<Tm, Tw>),
00683 SELECT(M), m)));
00684 }
00685
00686 }
00687
00688
00689
00690
00691
00692 template <typename W, typename M, typename Tm, typename Tw>
00693 void
00694 MetaElement<algebra::Series<W, M>, rat::exp<Tm, Tw> >::accept
00695 (const rat::ConstNodeVisitor<Tm, Tw>& v) const
00696 {
00697 this->value().accept(v);
00698 }
00699
00700 template <typename W, typename M, typename Tm, typename Tw>
00701 size_t
00702 MetaElement<algebra::Series<W, M>, rat::exp<Tm, Tw> >::depth() const
00703 {
00704 return this->value().depth();
00705 }
00706
00707 namespace algebra
00708 {
00709 template <class W, class M, class Tm, class Tw>
00710 Element<algebra::Series<W,M>, rat::exp<Tm,Tw> >
00711 op_choose(const algebra::Series<W,M>& s,
00712 SELECTOR2(rat::exp<Tm,Tw>))
00713 {
00714 Element<algebra::Series<W,M>, rat::exp<Tm, Tw> > e(s);
00715
00716 unsigned nb = RAND___(10);
00717 while (nb != 0)
00718 {
00719 --nb;
00720 unsigned t = RAND___(3);
00721 switch (t)
00722 {
00723
00724 case 0 :
00725 {
00726 e = e.star();
00727 continue;
00728 }
00729
00730 case 1 :
00731 {
00732 Element<algebra::Series<W,M>, rat::exp<Tm,Tw> >
00733 ep(s, s.monoid().choose(SELECT(Tm)));
00734 ep = ep * s.semiring().choose(SELECT(Tw));
00735 unsigned t = RAND___(2);
00736 if (t < 1)
00737 e = e + ep;
00738 else
00739 e = ep + e;
00740 continue;
00741 }
00742
00743 case 2 :
00744 {
00745 Element<algebra::Series<W,M>, rat::exp<Tm,Tw> >
00746 ep(s, s.monoid().choose(SELECT(Tm)));
00747 ep = ep * s.semiring().choose(SELECT(Tw));
00748 unsigned t = RAND___(2);
00749 if (t < 1)
00750 e = e * ep;
00751 else
00752 e = ep * e;
00753 continue;
00754 }
00755 }
00756 }
00757 return Element<algebra::Series<W,M>, rat::exp<Tm,Tw> >(s, e);
00758 }
00759
00760 }
00761
00762 }
00763
00764 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_HXX