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