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

# 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, 2005 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