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

- File List
- File Members

# partial_rat_exp.hxx

    00001 // partial_rat_exp.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, 2008, 2009 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_ALGORITHMS_INTERNAL_PARTIAL_RAT_EXP_HXX
    00018 # define VCSN_ALGORITHMS_INTERNAL_PARTIAL_RAT_EXP_HXX
    00019
    00020 # include <vaucanson/algorithms/internal/partial_rat_exp.hh>
    00021
    00022 namespace vcsn
    00023 {
    00024   /*-----------------.
    00025   | PartialExp class |
    00026   `-----------------*/
    00027
    00028   template <typename Series, typename T>
    00029   PartialExp<Series, T>::PartialExp(const exp_t &e):
    00030     rat_exp_(&e),
    00031     semiring_elt_list_(),
    00032     node_list_()
    00033   {
    00034     semiring_elt_list_.push_back(rat_exp_->structure().semiring().identity(
    00035       SELECT(typename semiring_elt_t::value_t)));
    00036   }
    00037
    00038   template <typename Series, typename T>
    00039   PartialExp<Series, T>::PartialExp(const PartialExp &other):
    00040     rat_exp_(other.rat_exp_),
    00041     semiring_elt_list_(other.semiring_elt_list_),
    00042     node_list_(other.node_list_)
    00043   { }
    00044
    00045   template <typename Series, typename T>
    00046   PartialExp<Series, T>::PartialExp(const exp_t &e, const semiring_elt_t& w):
    00047     rat_exp_(&e),
    00048     semiring_elt_list_(),
    00049     node_list_()
    00050   {
    00051     semiring_elt_list_.push_back(w);
    00052   }
    00053
    00054
    00055   template <typename Series, typename T>
    00056   template <typename M, typename W>
    00057   PartialExp<Series, T>&
    00058   PartialExp<Series, T>::insert(const rat::Node<M, W>* v)
    00059   {
    00060     // Break initial left products.
    00061     if (node_list_.empty() && v->what() == rat::Node<M, W>::prod)
    00062       {
    00063         const rat::Product<M, W>* p =
    00064           dynamic_cast<const rat::Product<M, W>*>(v);
    00065         insert(p->left_);
    00066
    00067         v = p->right_;
    00068       }
    00069
    00070     node_list_.push_back(v);
    00071     semiring_elt_list_.push_back(
    00072        rat_exp_->structure().semiring().
    00073           identity(SELECT(typename semiring_elt_t::value_t)));
    00074     return *this;
    00075   }
    00076
    00077   template <typename Series, typename T>
    00078   typename PartialExp<Series, T>::semiring_elt_list_t&
    00079   PartialExp<Series, T>::weights()
    00080   {
    00081     return semiring_elt_list_;
    00082   }
    00083
    00084   template <typename Series, typename T>
    00085   const typename PartialExp<Series, T>::semiring_elt_list_t&
    00086   PartialExp<Series, T>::weights() const
    00087   {
    00088     return semiring_elt_list_;
    00089   }
    00090
    00091   template <typename Series, typename T>
    00092   const typename PartialExp<Series, T>::node_list_t&
    00093   PartialExp<Series, T>::nodes() const
    00094   {
    00095     return node_list_;
    00096   }
    00097
    00098   template <typename Series, typename T>
    00099   typename PartialExp<Series, T>::node_list_t&
    00100   PartialExp<Series, T>::nodes()
    00101   {
    00102     return node_list_;
    00103   }
    00104
    00105   template <typename Series, typename T>
    00106   PartialExp<Series, T>&
    00107   PartialExp<Series, T>::operator<<=(const semiring_elt_t& w)
    00108   {
    00109     semiring_elt_list_.back() *= w;
    00110     return *this;
    00111   }
    00112
    00113   template <typename Series, typename T>
    00114   PartialExp<Series, T>&
    00115   PartialExp<Series, T>::operator>>=(const semiring_elt_t& w)
    00116   {
    00117     semiring_elt_list_.front() = w * semiring_elt_list_.front();
    00118     return *this;
    00119   }
    00120
    00121   template <typename Series, typename T>
    00122   const Series&
    00123   PartialExp<Series, T>::exp_structure() const
    00124   {
    00125     return rat_exp_->structure();
    00126   }
    00127
    00128   template <typename Series, typename T>
    00129   const T&
    00130   PartialExp<Series, T>::exp_value() const
    00131   {
    00132     return rat_exp_->value();
    00133   }
    00134
    00135   template <typename Series, typename T>
    00136   const typename PartialExp<Series, T>::exp_t&
    00137   PartialExp<Series, T>::exp() const
    00138   {
    00139     return *rat_exp_;
    00140   }
    00141
    00142   /*--------------------.
    00143   | PartialExp iterator |
    00144   `--------------------*/
    00145
    00146   template <typename Series, typename T>
    00147   template <bool IsConst>
    00148   PartialExp<Series, T>::internal_iterator<IsConst>::internal_iterator(
    00149     const semiring_elts_iterator_t& sit, const nodes_iterator_t& nit ):
    00150       semiring_elts_iterator_(sit),
    00151       nodes_iterator_(nit),
    00152       on_node_ (false)
    00153   {}
    00154
    00155   template <typename Series, typename T>
    00156   template <bool IsConst>
    00157   PartialExp<Series, T>::internal_iterator<IsConst>&
    00158   PartialExp<Series, T>::internal_iterator<IsConst>::operator++()
    00159   {
    00160     if (on_node_)
    00161       ++nodes_iterator_;
    00162     else
    00163       ++semiring_elts_iterator_;
    00164     on_node_ = not on_node_;
    00165     return *this;
    00166   }
    00167
    00168   template <typename Series, typename T>
    00169   template <bool IsConst>
    00170   PartialExp<Series, T>::internal_iterator<IsConst>
    00171   PartialExp<Series, T>::internal_iterator<IsConst>::operator++(int)
    00172   {
    00173     internal_iterator old = *this;
    00174
    00175     if (on_node_)
    00176       ++nodes_iterator_;
    00177     else
    00178       ++semiring_elts_iterator_;
    00179     on_node_ = not on_node_;
    00180     return old;
    00181   }
    00182
    00183   template <typename Series, typename T>
    00184   template <bool IsConst>
    00185   typename PartialExp<Series, T>::template internal_iterator<IsConst>::
    00186   semiring_elt_ref_t
    00187   PartialExp<Series, T>::internal_iterator<IsConst>::semiring_elt() const
    00188   {
    00189     assertion(!on_node_);
    00190     return *semiring_elts_iterator_;
    00191   }
    00192
    00193   template <typename Series, typename T>
    00194   template <bool IsConst>
    00195   typename PartialExp<Series, T>::template internal_iterator<IsConst>::
    00196   node_ref_t
    00197   PartialExp<Series, T>::internal_iterator<IsConst>::node() const
    00198   {
    00199     assertion(on_node_);
    00200     return *nodes_iterator_;
    00201   }
    00202
    00203   template <typename Series, typename T>
    00204   template <bool IsConst>
    00205   bool
    00206   PartialExp<Series, T>::internal_iterator<IsConst>::on_node() const
    00207   {
    00208     return on_node_;
    00209   }
    00210
    00211   template <typename Series, typename T>
    00212   template <bool IsConst>
    00213   bool
    00214   PartialExp<Series, T>::internal_iterator<IsConst>::operator!=(const internal_iterator& other)
    00215   {
    00216     return nodes_iterator_ != other.nodes_iterator_ or
    00217       semiring_elts_iterator_ != other.semiring_elts_iterator_;
    00218   }
    00219
    00220   template <typename Series, typename T>
    00221   template <bool IsConst>
    00222   bool
    00223   PartialExp<Series, T>::internal_iterator<IsConst>::operator==(const internal_iterator& other)
    00224   {
    00225     return nodes_iterator_ == other.nodes_iterator_ and
    00226       semiring_elts_iterator_ == other.semiring_elts_iterator_;
    00227   }
    00228
    00229   template <typename Series, typename T>
    00230   typename PartialExp<Series, T>::iterator
    00231   PartialExp<Series, T>::begin()
    00232   {
    00233     return iterator(semiring_elt_list_.begin(), node_list_.begin());
    00234   }
    00235
    00236   template <typename Series, typename T>
    00237   typename PartialExp<Series, T>::const_iterator
    00238   PartialExp<Series, T>::begin() const
    00239   {
    00240     return const_iterator(semiring_elt_list_.begin(), node_list_.begin());
    00241   }
    00242
    00243   template <typename Series, typename T>
    00244   typename PartialExp<Series, T>::iterator
    00245   PartialExp<Series, T>::end()
    00246   {
    00247     return iterator(semiring_elt_list_.end(), node_list_.end());
    00248   }
    00249
    00250   template <typename Series, typename T>
    00251   typename PartialExp<Series, T>::const_iterator
    00252   PartialExp<Series, T>::end() const
    00253   {
    00254     return const_iterator(semiring_elt_list_.end(), node_list_.end());
    00255   }
    00256
    00257   /*---------------------.
    00258   | PartialExp functions |
    00259   `---------------------*/
    00260
    00261   template <typename S, typename T>
    00262   std::ostream& operator<< (std::ostream& o, const PartialExp<S, T>& e)
    00263   {
    00264     typename PartialExp<S, T>::const_iterator i = e.begin();
    00265
    00266     o << '[' << i.semiring_elt();
    00267
    00268     for (i++; i != e.end(); ++i)
    00269     {
    00270       if (i.on_node())
    00271         {
    00272           typename PartialExp<S, T>::series_set_elt_value_t v(i.node());
    00273           typename PartialExp<S, T>::exp_t val(e.exp().structure(), v);
    00274           o << '|' << val;
    00275         }
    00276       else
    00277         {
    00278           o << '|' << i.semiring_elt();
    00279         }
    00280     }
    00281     return o << ']';
    00282   }
    00283
    00284   template <typename S, typename T, typename M, typename W>
    00285   PartialExp<S, T> prat_exp_convert(const Element<S, T>& exp,
    00286                                     const rat::Node<M, W>* node)
    00287   {
    00288     typedef typename PartialExp<S, T>::semiring_elt_t   semiring_elt_t;
    00289     semiring_elt_t      lw = exp.structure().semiring().identity(
    00290       SELECT(typename semiring_elt_t::value_t));
    00291     semiring_elt_t      rw = exp.structure().semiring().identity(
    00292       SELECT(typename semiring_elt_t::value_t));
    00293
    00294     while (node->what() == rat::Node<M, W>::lweight or
    00295            node->what() == rat::Node<M, W>::rweight)
    00296       if (node->what() == rat::Node<M, W>::lweight)
    00297       {
    00298         const rat::LeftWeighted<M, W>* p =
    00299           dynamic_cast<const rat::LeftWeighted<M, W>*>(node);
    00300         lw = p->weight_ * lw;
    00301         node = p->child_;
    00302       }
    00303       else
    00304       {
    00305         const rat::RightWeighted<M, W>* p =
    00306           dynamic_cast<const rat::RightWeighted<M, W>*>(node);
    00307         rw *= p->weight_;
    00308         node = p->child_;
    00309       }
    00310     PartialExp<S, T>    res(exp);
    00311     res.insert(node);
    00312     res >>= lw;
    00313     res <<= rw;
    00314     return res;
    00315   }
    00316
    00317   template <typename S, typename T>
    00318   PartialExp<S, T> prat_exp_convert(const Element<S, T>& exp)
    00319   {
    00320     return prat_exp_convert(exp, exp.value().base());
    00321   }
    00322
    00323   template <typename S, typename T>
    00324   std::list<PartialExp<S, T> > prat_exp_convert(const std::list<Element<S, T> >& listexp)
    00325   {
    00326     std::list<PartialExp<S, T> > res;
    00327     for (typename std::list<Element<S, T> >::const_iterator it =
    00328            listexp.begin(); it != listexp.end(); ++it)
    00329       res.push_back(prat_exp_convert(*it, it->value().base()));
    00330     return res;
    00331   }
    00332
    00333   template <typename S, typename T>
    00334   bool operator< (const PartialExp<S, T>& e1, const PartialExp<S, T>& e2)
    00335   {
    00336     typedef
    00337     typename PartialExp<S, T>::series_set_elt_value_t   series_set_elt_value_t;
    00338     typename PartialExp<S, T>::const_iterator i1 = e1.begin();
    00339     typename PartialExp<S, T>::const_iterator i2 = e2.begin();
    00340
    00341     if (i1.semiring_elt() != i2.semiring_elt())
    00342       return (i1.semiring_elt() < i2.semiring_elt());
    00343
    00344     for (i1++, i2++; i1 != e1.end() and i2 != e2.end(); )
    00345     {
    00346       if (series_set_elt_value_t(i1.node()) != series_set_elt_value_t(i2.node()))
    00347         break;
    00348       ++i1;
    00349       ++i2;
    00350       if (i1.semiring_elt() != i2.semiring_elt())
    00351         break;
    00352       ++i1;
    00353       ++i2;
    00354     }
    00355     if (i1 == e1.end() || i2 == e2.end())
    00356       return (i1 == e1.end() && i2 != e2.end());
    00357     else if (i1.on_node())
    00358       return series_set_elt_value_t(i1.node()) < series_set_elt_value_t(i2.node());
    00359     else
    00360       return i1.semiring_elt() < i2.semiring_elt();
    00361   }
    00362
    00363   template <typename S, typename T>
    00364   bool operator== (const PartialExp<S, T>& e1, const PartialExp<S, T>& e2)
    00365   {
    00366     typedef
    00367     typename PartialExp<S, T>::series_set_elt_value_t   series_set_elt_value_t;
    00368     typename PartialExp<S, T>::const_iterator i1 = e1.begin();
    00369     typename PartialExp<S, T>::const_iterator i2 = e2.begin();
    00370
    00371     if (i1.semiring_elt() != i2.semiring_elt())
    00372       return false;
    00373
    00374     for (i1++, i2++; i1 != e1.end() and i2 != e2.end(); )
    00375     {
    00376       if (series_set_elt_value_t(i1.node()) != series_set_elt_value_t(i2.node()))
    00377         break;
    00378       ++i1;
    00379       ++i2;
    00380       if (i1.semiring_elt() != i2.semiring_elt())
    00381         break;
    00382       ++i1;
    00383       ++i2;
    00384     }
    00385     return (i1 == e1.end() && i2 == e2.end());
    00386   }
    00387
    00388   template <typename S, typename T>
    00389   bool unweighted_inf(const PartialExp<S, T>& e1, const PartialExp<S, T>& e2)
    00390   {
    00391     typedef
    00392     typename PartialExp<S, T>::series_set_elt_value_t   series_set_elt_value_t;
    00393     typename PartialExp<S, T>::const_iterator i1 = e1.begin();
    00394     typename PartialExp<S, T>::const_iterator i2 = e2.begin();
    00395
    00396     for (i1++, i2++; i1 != e1.end() and i2 != e2.end(); )
    00397     {
    00398       if (series_set_elt_value_t(i1.node()) != series_set_elt_value_t(i2.node()))
    00399         break;
    00400       ++i1;
    00401       ++i2;
    00402       if (i1.semiring_elt() != i2.semiring_elt())
    00403         break;
    00404       ++i1;
    00405       ++i2;
    00406     }
    00407     if (i1 == e1.end() || i2 == e2.end())
    00408       return (i1 == e1.end() && i2 != e2.end());
    00409     else if (i1.on_node())
    00410       return series_set_elt_value_t(i1.node()) < series_set_elt_value_t(i2.node());
    00411     else
    00412       return i1.semiring_elt() < i2.semiring_elt();
    00413   }
    00414
    00415   template <typename S, typename T>
    00416   bool unweighted_eq(const PartialExp<S, T>& e1, const PartialExp<S, T>& e2)
    00417   {
    00418     typedef
    00419     typename PartialExp<S, T>::series_set_elt_value_t   series_set_elt_value_t;
    00420     typename PartialExp<S, T>::const_iterator i1 = e1.begin();
    00421     typename PartialExp<S, T>::const_iterator i2 = e2.begin();
    00422
    00423     for (i1++, i2++; i1 != e1.end() and i2 != e2.end(); )
    00424     {
    00425       if (series_set_elt_value_t(i1.node()) != series_set_elt_value_t(i2.node()))
    00426         break;
    00427       ++i1;
    00428       ++i2;
    00429       if (i1.semiring_elt() != i2.semiring_elt())
    00430         break;
    00431       ++i1;
    00432       ++i2;
    00433     }
    00434     return (i1 == e1.end() && i2 == e2.end());
    00435   }
    00436
    00437 } // vcsn
    00438
    00439 #endif // ! VCSN_ALGORITHMS_INTERNAL_PARTIAL_RAT_EXP_HXX