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

Generated on Thu Dec 13 16:03:00 2007 for Vaucanson by  doxygen 1.5.4