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, 2008 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 <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       // case E + 0
00137       if (arg.base()->what() == rat::Node<Tm, Tw>::zero)
00138         return ;
00139 
00140       // case 0 + E
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       // case 0 . E -> 0
00181       if (this_type == node_t::zero)
00182         return;
00183 
00184       // case E . 0 -> 0
00185       if (arg_type == node_t::zero)
00186       {
00187         delete dst.base();
00188         dst.base() = new n_zero_t;
00189         return;
00190       }
00191 
00192       // case 1 . E -> E
00193       if (this_type == node_t::one)
00194       {
00195         delete dst.base();
00196         dst.base() = arg.base()->clone();
00197         return;
00198       }
00199 
00200       // case E . 1 -> E
00201       if (arg_type == node_t::one)
00202       {
00203         return;
00204       }
00205 
00206       // case E . {k'} 1 -> E {k'}
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       // case {k} 1 . E -> {k} E
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       // general case : {k} E . E'
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     | foreign constructors |
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       // FIXME: this is completely broken. It should break up m_value
00271       // into letters.
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       // FIXME: this is completely broken also.
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     | star |
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       // rewrite 0* as 1
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     | foreign addition with monoid elements |
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     | foreign addition with semiring elements |
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     | foreign multiplication by semiring elements |
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       // case 0 {k} -> 0
00454       if (this_type == node_t::zero)
00455         return;
00456 
00457       // case E {1} -> E
00458       if (w == identity_value(SELECT(W), SELECT(oTw)))
00459         return;
00460 
00461       // case E {0} -> 0
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       // case 1 {k} -> {k} 1
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       // case c {k} -> {k} c  (where c is a letter, not a word)
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       // case (E {k'}) {k} -> E {k'k}
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       // [1] case ({k'} E) {k} -> {k'} (E {k})
00499       // [2] case ({k'} c) {k} -> {k'k} c  if c is a letter
00500       // (Note: case [2] is like if you had applied case [1]
00501       // followed by the c {k} -> {k} c, and then the
00502       // {k'} (E  {k}) -> {k'k} E rewritings.)
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       // case ({k'} E) {k} -> general case
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       // case {k} 0 -> 0
00562       if (this_type == node_t::zero)
00563         return ret;
00564 
00565       // case {k} 1 -> general case
00566 
00567       // case {0} E -> 0
00568       if (w == zero_value(SELECT(W), SELECT(oTw)))
00569       { return rat::exp<Tm, Tw>::zero(); }
00570 
00571       // case {1} E -> E
00572       if (w == identity_value(SELECT(W), SELECT(oTw)))
00573         return ret;
00574 
00575       // case {k} ({k'} E) -> {k k'} E
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       // general case {k} E
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       // FIXME Should not rebuild the serie from stratch
00628       // Should use some kind of visitor and update the tree
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   } // ! algebra
00655 
00656   /*----------------------------------------------------------------------------.
00657   | MetaElement<algebra::SeriesBase<algebra::Series<W, M> >, rat::exp<Tm, Tw> > |
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       // FIXME : add global constants to do this !
00684       unsigned nb = RAND___(10);
00685       while (nb != 0)
00686       {
00687         --nb;
00688         unsigned t = RAND___(3);
00689         switch (t)
00690         {
00691           // star
00692           case 0 :
00693             {
00694               e = e.star();
00695               continue;
00696             }
00697             // plus
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             // mult
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   } // ! algebra
00729 
00730 } // ! vcsn
00731 
00732 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_HXX

Generated on Thu Oct 9 20:22:36 2008 for Vaucanson by  doxygen 1.5.1