Vaucanson 1.4
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