- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

# krat.hxx

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