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

# krat_exp_partial_derivation.hxx

    00001 // krat_exp_partial_derivation.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_PARTIAL_DERIVATION_HXX
    00018 # define VCSN_ALGORITHMS_KRAT_EXP_PARTIAL_DERIVATION_HXX
    00019
    00020 # include <vaucanson/algorithms/krat_exp_partial_derivation.hh>
    00021
    00022 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh>
    00023 # include <vaucanson/algorithms/krat_exp_constant_term.hh>
    00024
    00025 namespace vcsn {
    00026
    00027   namespace algebra {
    00028
    00029     // Some operators are defined in order to make algorithm clearer
    00030     // and efficient
    00031
    00032     // operator^ apply * between each element of the set and the other
    00033     // argument
    00034     template <typename T, typename U>
    00035     std::set<T> operator^ (std::set<T> set, U other)
    00036     {
    00037       typedef typename std::set<T>::iterator    iterator;
    00038       std::set<T>       result;
    00039       for (iterator i = set.begin(); i != set.end(); ++i)
    00040         result.insert(*i * other);
    00041       return result;
    00042     }
    00043
    00044     template <typename T, typename U>
    00045     std::set<T> operator^ (U other, std::set<T> set)
    00046     {
    00047       typedef typename std::set<T>::iterator    iterator;
    00048       std::set<T>       result;
    00049       for (iterator i = set.begin(); i != set.end(); ++i)
    00050         result.insert(other * *i);
    00051       return result;
    00052     }
    00053
    00054     // operator+ make the union of two set
    00055     template <typename T>
    00056     std::set<T> operator+ (std::set<T> s1, std::set<T> s2)
    00057     {
    00058       std::set<T>       result;
    00059       merge(s1.begin(), s1.end(),
    00060             s2.begin(), s2.end(),
    00061             inserter(result, result.begin()));
    00062       return result;
    00063     }
    00064
    00065     // It is a first implementation of partial derivate.
    00066     // It simply apply the definition of partial derivates.
    00067     template <class Series, class T, class Dispatch>
    00068     struct KRatExpPartialDerivation : algebra::KRatExpMatcher<
    00069       KRatExpPartialDerivation<Series, T, Dispatch>,
    00070       T,
    00071       std::set<Element<Series, T> >,
    00072       Dispatch
    00073       >
    00074     {
    00075       typedef KRatExpPartialDerivation<Series, T, Dispatch>     self_t;
    00076       typedef Element<Series, T>                                        exp_t;
    00077       typedef std::set<exp_t>                                   set_t;
    00078       typedef set_t                                             return_type;
    00079       typedef typename set_t::iterator  iterator;
    00080       typedef typename Element<Series, T>::semiring_elt_t               semiring_elt_t;
    00081       typedef typename semiring_elt_t::value_t                          semiring_elt_value_t;
    00082       typedef typename Element<Series, T>::monoid_elt_t         monoid_elt_t;
    00083       typedef typename monoid_elt_t::value_t                    monoid_elt_value_t;
    00084       typedef typename monoid_elt_t::set_t                      monoid_t;
    00085       typedef typename monoid_t::alphabet_t                     alphabet_t;
    00086       typedef typename alphabet_t::letter_t                     letter_t;
    00087       INHERIT_CONSTRUCTORS(self_t, T, semiring_elt_t, Dispatch);
    00088
    00089       KRatExpPartialDerivation(const Element<Series, T>& exp,
    00090                                letter_t                  a) :
    00091         undefined(false),
    00092         exp_(exp),
    00093         a_(a)
    00094       {}
    00095
    00096       Element<Series, T> series(const T& e)
    00097       {
    00098         return Element<Series, T>(exp_.structure(), e);
    00099       }
    00100
    00101       MATCH__(Product, lhs, rhs)
    00102       {
    00103         std::pair<semiring_elt_t, bool> ret = constant_term(series(lhs));
    00104         if (ret.second == false)
    00105           {
    00106             undefined = true;
    00107             return return_type();
    00108           }
    00109         if (ret.first !=
    00110             exp_.structure().semiring().zero(SELECT(semiring_elt_value_t)))
    00111           return (match(lhs) ^ rhs) + (ret.first ^ match(rhs));
    00112         else
    00113           return (match(lhs) ^ rhs);
    00114       }
    00115       END
    00116
    00117       MATCH__(Sum, lhs, rhs)
    00118       {
    00119         return match(lhs) + match(rhs);
    00120       }
    00121       END
    00122
    00123       MATCH_(Star, e)
    00124       {
    00125         std::pair<semiring_elt_t, bool> ret = constant_term(series(e));
    00126         if ((ret.second == false) || (ret.first.starable() == false))
    00127           {
    00128             undefined = true;
    00129             return return_type();
    00130           }
    00131         return ret.first.star() ^ (match(e) ^ e.clone().star());
    00132       }
    00133       END
    00134
    00135       MATCH__(LeftWeight, w, e)
    00136       {
    00137         return semiring_elt_t(w) ^ match(e);
    00138       }
    00139       END
    00140
    00141       MATCH__(RightWeight, e, w)
    00142       {
    00143         return match(e) ^ semiring_elt_t(w);
    00144       }
    00145       END
    00146
    00147       MATCH_(Constant, m)
    00148       {
    00149         return_type     res;
    00150         if (m[0] == a_)
    00151           {
    00152             if (m.length() == 1)
    00153               res.insert(algebra::identity_as<T>::of(exp_.structure()));
    00154             else
    00155               res.insert(Element<Series, T> (exp_.structure(), m.substr(1)));
    00156           }
    00157         return res;
    00158       }
    00159       END
    00160
    00161       MATCH(Zero)
    00162       {
    00163         return return_type();
    00164       }
    00165       END
    00166
    00167       MATCH(One)
    00168       {
    00169         return return_type();
    00170       }
    00171       END
    00172
    00173       bool undefined;
    00174
    00175     private:
    00176       Element<Series, T>  exp_;
    00177       letter_t          a_;
    00178     };
    00179
    00180   } // algebra
    00181
    00182   template <class Series, class T, class Letter>
    00183   std::pair<std::set<Element<Series, T> >, bool>
    00184   partial_derivate(const Element<Series, T>& exp,
    00185                    Letter a)
    00186   {
    00187     algebra::KRatExpPartialDerivation<Series, T, algebra::DispatchFunction<T> >
    00188       matcher(exp, a);
    00189     std::set<Element<Series, T> > ret = matcher.match(exp.value());
    00190     if (matcher.undefined)
    00191       return std::make_pair(ret, false);
    00192     return std::make_pair(ret, true);
    00193   }
    00194
    00195 } // vcsn
    00196
    00197 #endif // ! VCSN_ALGORITHMS_KRAT_EXP_PARTIAL_DERIVATION_HXX