krat_exp_expand.hxx

00001 // krat_exp_expand.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 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_KRAT_EXP_EXPAND_HXX
00018 # define VCSN_ALGORITHMS_KRAT_EXP_EXPAND_HXX
00019 
00020 # include <list>
00021 # include <map>
00022 
00023 # include <vaucanson/algorithms/krat_exp_expand.hh>
00024 
00025 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh>
00026 
00027 namespace vcsn
00028 {
00029 
00030   namespace algebra {
00031 
00032     // This is a trait to get more easily used types.
00033     template <typename S, typename T>
00034     struct pseudo_exp_list
00035     {
00036       typedef Element<S, T>                             exp_t;
00037       typedef std::list<exp_t>                          exp_list_t;
00038       typedef typename exp_t::semiring_elt_t            semiring_elt_t;
00039       typedef std::map<exp_list_t, semiring_elt_t>      ret_t;
00040     };
00041 
00042     // The Expander class. It break up the expression to build a map
00043     // and then rebuild it.
00044     template <class Series, class T, class Dispatch>
00045     struct KRatExpExpander : algebra::KRatExpMatcher<
00046       KRatExpExpander<Series, T, Dispatch>,
00047       T,
00048       typename pseudo_exp_list<Series, T>::ret_t,
00049       Dispatch
00050       >
00051     {
00052     public:
00053       typedef pseudo_exp_list<Series, T>                        trait;
00054       typedef typename trait::exp_t                             exp_t;
00055       typedef typename trait::ret_t                             return_type;
00056       typedef typename trait::exp_list_t                        exp_list_t;
00057       typedef KRatExpExpander<Series, T, Dispatch>              self_t;
00058       typedef typename Element<Series, T>::semiring_elt_t       semiring_elt_t;
00059       typedef typename semiring_elt_t::value_t                  semiring_elt_value_t;
00060       typedef typename Element<Series, T>::monoid_elt_t         monoid_elt_t;
00061       typedef typename monoid_elt_t::set_t                      monoid_t;
00062       typedef typename monoid_t::alphabet_t                     alphabet_t;
00063       typedef typename alphabet_t::letter_t                     letter_t;
00064       INHERIT_CONSTRUCTORS(self_t, T, semiring_elt_t, Dispatch);
00065 
00066       KRatExpExpander(const exp_t& exp) :
00067         exp_(exp)
00068       {}
00069 
00070       // Some useful internal functions.
00071     private:
00072       // Convert the return_type into a rational expression.
00073       exp_t convert(const return_type& l)
00074       {
00075         typedef typename return_type::const_iterator    iterator;
00076         typedef typename exp_list_t::const_iterator     sub_iterator;
00077 
00078         exp_t result = exp_.structure().zero(SELECT(T));
00079 
00080         for (iterator i = l.begin(); i != l.end(); ++i)
00081         {
00082           exp_list_t    l = i->first;
00083           exp_t         e = l.front();
00084           for (sub_iterator j = ++l.begin(); j != l.end(); ++j)
00085             e *= *j;
00086           result += i->second * e;
00087         }
00088 
00089         return result;
00090       }
00091 
00092       // Convert a standard expression into the corresponding breaked one.
00093       return_type convert(const exp_t& e)
00094       {
00095         exp_list_t      exp_list;
00096         exp_list.push_front(e);
00097 
00098         return_type     result;
00099         result[exp_list] =
00100           exp_.structure().semiring().identity(SELECT(semiring_elt_value_t));
00101 
00102         return result;
00103       }
00104 
00105       // The union of two lists implemented by a map. If an element is in the
00106       // two lists then the weights are added.
00107       return_type list_union(const return_type& left,
00108                              const return_type& right)
00109       {
00110         typedef typename return_type::const_iterator    const_iterator;
00111         typedef typename return_type::iterator          iterator;
00112 
00113         return_type     result(left);
00114         for (const_iterator i = right.begin(); i != right.end(); ++i)
00115         {
00116           iterator j = result.find(i->first);
00117 
00118           if (j != result.end())
00119             j->second += i->second;
00120           else
00121             result.insert(*i);
00122         }
00123 
00124         return result;
00125       }
00126 
00127       // Compute the concatenation of two list, regarding to handled elements.
00128       exp_list_t list_concat(const exp_list_t& left, const exp_list_t& right)
00129       {
00130         typedef typename exp_list_t::const_iterator     const_iterator;
00131 
00132         typename T::n_const_t* left_node =
00133           dynamic_cast<typename T::n_const_t*>(left.back().value().base());
00134         typename T::n_const_t* right_node =
00135           dynamic_cast<typename T::n_const_t*>(right.front().value().base());
00136 
00137         std::list<exp_t>        result(left);
00138 
00139         if (left_node and right_node)
00140         {
00141           result.back() = exp_t(exp_.structure(),
00142                                 left_node->value_ + right_node->value_);
00143           for (const_iterator i = ++right.begin(); i != right.end(); ++i)
00144             result.push_back(*i);
00145         }
00146         else
00147           for (const_iterator i = right.begin(); i != right.end(); ++i)
00148             result.push_back(*i);
00149         return result;
00150       }
00151 
00152       // Public functions.
00153     public:
00154       // This function convert the result the original form.
00155       exp_t get()
00156       {
00157         return_type l = match(exp_.value());
00158         return convert(l);
00159       }
00160 
00161       // Match functions.
00162       MATCH__(Product, lhs, rhs)
00163       {
00164         typedef typename return_type::iterator          iterator;
00165 
00166         return_type llist = match(lhs);
00167         return_type rlist = match(rhs);
00168         return_type result;
00169 
00170         for (iterator i = llist.begin(); i != llist.end(); ++i)
00171           for (iterator j = rlist.begin(); j != rlist.end(); ++j)
00172             result[list_concat(i->first, j->first)] = i->second * j->second;
00173         return result;
00174       }
00175       END
00176 
00177       MATCH__(Sum, lhs, rhs)
00178       {
00179         return list_union(match(lhs), match(rhs));
00180       }
00181       END
00182 
00183       MATCH_(Star, e)
00184       {
00185         return_type l = match(e);
00186         return convert(convert(l).star());
00187       }
00188       END
00189 
00190       MATCH__(LeftWeight, w, e)
00191       {
00192         typedef typename return_type::iterator          iterator;
00193 
00194         return_type     l = match(e);
00195         return_type     result;
00196 
00197         for (iterator i = l.begin(); i != l.end(); ++i)
00198           result[i->first] = semiring_elt_t(w) * i->second;
00199         return result;
00200       }
00201       END
00202 
00203       MATCH__(RightWeight, e, w)
00204       {
00205         typedef typename return_type::iterator          iterator;
00206 
00207         return_type     l = match(e);
00208         return_type     result;
00209 
00210         for (iterator i = l.begin(); i != l.end(); ++i)
00211           result[i->first] = i->second * semiring_elt_t(w);
00212         return result;
00213       }
00214       END
00215 
00216       MATCH_(Constant, m)
00217       {
00218         return convert(exp_t(exp_.structure(), m));
00219       }
00220       END
00221 
00222       MATCH(Zero)
00223       {
00224         return convert(exp_.structure().zero(SELECT(T)));
00225       }
00226       END
00227 
00228       MATCH(One)
00229       {
00230         return convert(exp_.structure().identity(SELECT(T)));
00231       }
00232       END
00233 
00234     private:
00235         Element<Series, T>      exp_;
00236     };
00237 
00238     template <class S, class E>
00239     E do_expand(const algebra::SeriesBase<S>&, const E& exp)
00240     {
00241       typedef typename E::value_t       T;
00242 
00243       KRatExpExpander< S, T, algebra::DispatchFunction<T> >     matcher(exp);
00244       return matcher.get();
00245     }
00246 
00247     template <class Series, class T>
00248     Element<Series, T>
00249     expand(const Element<Series, T>& exp)
00250     {
00251       return do_expand(exp.structure(), exp);
00252     }
00253 
00254   } // algebra
00255 
00256 } // vcsn
00257 
00258 #endif // ! VCSN_ALGORITHMS_KRAT_EXP_EXPAND_HXX

Generated on Fri Jul 28 12:18:39 2006 for Vaucanson by  doxygen 1.4.6