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

- File List
- File Members

# 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, 2008, 2011 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 breaks 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 lists
    00128       exp_list_t list_concat(const exp_list_t& left, const exp_list_t& right)
    00129       {
    00130
    00131         typename T::node_t* lnode = left.back().value().base();
    00132         typename T::node_t* rnode = right.front().value().base();
    00133
    00134         // Handle concatenations when one operand is a constant (ONE or ZERO)
    00135         if (dynamic_cast<typename T::n_one_t*>(lnode))
    00136           return right;
    00137         if (dynamic_cast<typename T::n_one_t*>(rnode))
    00138           return left;
    00139         if (dynamic_cast<typename T::n_zero_t*>(lnode))
    00140           return left;
    00141         if (dynamic_cast<typename T::n_zero_t*>(rnode))
    00142           return right;
    00143
    00144         typedef typename exp_list_t::const_iterator const_iterator;
    00145         std::list<exp_t>        result(left);
    00146
    00147         // If the last exp from left and the first exp from right
    00148         // are words, concatenate them.
    00149         typename T::n_const_t* left_node =
    00150           dynamic_cast<typename T::n_const_t*>(lnode);
    00151         typename T::n_const_t* right_node =
    00152           dynamic_cast<typename T::n_const_t*>(rnode);
    00153         if (left_node and right_node)
    00154         {
    00155           result.back() = exp_t(exp_.structure(),
    00156                                 left_node->value_ + right_node->value_);
    00157           for (const_iterator i = ++right.begin(); i != right.end(); ++i)
    00158             result.push_back(*i);
    00159         }
    00160         else
    00161           for (const_iterator i = right.begin(); i != right.end(); ++i)
    00162             result.push_back(*i);
    00163         return result;
    00164       }
    00165
    00166       // Public functions.
    00167     public:
    00168       // This function convert the result the original form.
    00169       exp_t get()
    00170       {
    00171         return_type l = this->match(exp_.value());
    00172         return convert(l);
    00173       }
    00174
    00175       // Match functions.
    00176       MATCH__(Product, lhs, rhs)
    00177       {
    00178         typedef typename return_type::iterator          iterator;
    00179
    00180         return_type llist = this->match(lhs);
    00181         return_type rlist = this->match(rhs);
    00182         return_type result;
    00183
    00184         for (iterator i = llist.begin(); i != llist.end(); ++i)
    00185           for (iterator j = rlist.begin(); j != rlist.end(); ++j)
    00186             {
    00187               exp_list_t p = list_concat(i->first, j->first);
    00188
    00189               iterator pi = result.find(p);
    00190               if (pi != result.end())
    00191                 pi->second += i->second * j->second;
    00192               else
    00193                 result[p] = i->second * j->second;
    00194             }
    00195         return result;
    00196       }
    00197       END
    00198
    00199       MATCH__(Sum, lhs, rhs)
    00200       {
    00201         return list_union(this->match(lhs), this->match(rhs));
    00202       }
    00203       END
    00204
    00205       MATCH_(Star, e)
    00206       {
    00207         return_type l = this->match(e);
    00208         return convert(convert(l).star());
    00209       }
    00210       END
    00211
    00212       MATCH__(LeftWeight, w, e)
    00213       {
    00214         typedef typename return_type::iterator          iterator;
    00215
    00216         return_type     l = this->match(e);
    00217         return_type     result;
    00218
    00219         for (iterator i = l.begin(); i != l.end(); ++i)
    00220           result[i->first] = semiring_elt_t(w) * i->second;
    00221         return result;
    00222       }
    00223       END
    00224
    00225       MATCH__(RightWeight, e, w)
    00226       {
    00227         typedef typename return_type::iterator          iterator;
    00228
    00229         return_type     l = this->match(e);
    00230         return_type     result;
    00231
    00232         for (iterator i = l.begin(); i != l.end(); ++i)
    00233           result[i->first] = i->second * semiring_elt_t(w);
    00234         return result;
    00235       }
    00236       END
    00237
    00238       MATCH_(Constant, m)
    00239       {
    00240         return convert(exp_t(exp_.structure(), m));
    00241       }
    00242       END
    00243
    00244       MATCH(Zero)
    00245       {
    00246         return convert(exp_.structure().zero(SELECT(T)));
    00247       }
    00248       END
    00249
    00250       MATCH(One)
    00251       {
    00252         return convert(exp_.structure().identity(SELECT(T)));
    00253       }
    00254       END
    00255
    00256     private:
    00257         Element<Series, T>      exp_;
    00258     };
    00259
    00260   } // ! algebra
    00261
    00262   template <class S, class E>
    00263   E do_expand(const algebra::SeriesBase<S>&, const E& exp)
    00264   {
    00265     typedef typename E::value_t T;
    00266
    00267     algebra::KRatExpExpander< S, T, algebra::DispatchFunction<T> >      matcher(exp);
    00268     return matcher.get();
    00269   }
    00270
    00271   template <class Series, class T>
    00272   Element<Series, T>
    00273   expand(const Element<Series, T>& exp)
    00274   {
    00275     return do_expand(exp.structure(), exp);
    00276   }
    00277
    00278 } // ! vcsn
    00279
    00280 #endif // ! VCSN_ALGORITHMS_KRAT_EXP_EXPAND_HXX