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