Vaucanson 1.4
krat_exp_constant_term.hxx
00001 // krat_exp_constant_term.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, 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_CONSTANT_TERM_HXX
00018 # define VCSN_ALGORITHMS_KRAT_EXP_CONSTANT_TERM_HXX
00019 
00020 # include <vaucanson/algorithms/krat_exp_constant_term.hh>
00021 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh>
00022 
00023 namespace vcsn {
00024 
00033   template <class Series, class T, class Dispatch>
00034   class ConstantTermEval : public algebra::KRatExpMatcher<
00035     ConstantTermEval<Series, T, Dispatch>,
00036     T,
00037     typename Element<Series, T>::semiring_elt_t,
00038     Dispatch
00039     >
00040   {
00041   public:
00042     typedef ConstantTermEval<Series, T, Dispatch>       self_t;
00043     typedef typename Element<Series, T>::semiring_elt_t       return_type;
00044     typedef typename Element<Series, T>::semiring_elt_t       semiring_elt_t;
00045     typedef typename semiring_elt_t::value_t                    semiring_elt_value_t;
00046     INHERIT_CONSTRUCTORS(self_t, T, semiring_elt_t, Dispatch);
00047 
00048     ConstantTermEval(const Element<Series, T>& exp) :
00049       undefined(false),
00050       exp_(exp)
00051     {}
00052 
00053     MATCH__(Product, lhs, rhs)
00054     {
00055       return this->match(lhs) * this->match(rhs);
00056     }
00057     END
00058 
00059     MATCH__(Sum, lhs, rhs)
00060     {
00061       return this->match(lhs) + this->match(rhs);
00062     }
00063     END
00064 
00065     MATCH_(Star, node)
00066     {
00067       semiring_elt_t ret = this->match(node);
00068       if (ret.starable())
00069         return star(ret);
00070       undefined = true;
00071       return ret;
00072     }
00073     END
00074 
00075     MATCH__(LeftWeight, w, node)
00076     {
00077       return w * this->match(node);
00078     }
00079     END
00080 
00081     MATCH__(RightWeight, node, w)
00082     {
00083       return this->match(node) * w;
00084     }
00085     END
00086 
00087     MATCH_(Constant, m)
00088     {
00089       return exp_.structure().semiring().zero(SELECT(semiring_elt_value_t));
00090     }
00091     END
00092 
00093     MATCH(Zero)
00094     {
00095       return exp_.structure().semiring().zero(SELECT(semiring_elt_value_t));
00096     }
00097     END
00098 
00099     MATCH(One)
00100     {
00101       return exp_.structure().semiring().identity(SELECT(semiring_elt_value_t));
00102     }
00103     END
00104 
00105     bool undefined;
00106 
00107   private:
00108     Element<Series, T> exp_;
00109   };
00110 
00111   template <class Series, class T>
00112   std::pair<typename Element<Series, T>::semiring_elt_t, bool>
00113   constant_term(const Element<Series, T>& exp)
00114   {
00115     typedef typename Element<Series, T>::semiring_elt_t     semiring_elt_t;
00116     ConstantTermEval<Series, T, algebra::DispatchFunction<T> > matcher(exp);
00117     semiring_elt_t v = matcher.match(exp.value());
00118     if (matcher.undefined)
00119       return std::make_pair(v, false);
00120     return std::make_pair(v, true);
00121   }
00122 
00123 } // vcsn
00124 
00125 #endif // ! VCSN_ALGORITHMS_KRAT_EXP_CONSTANT_TERM_HXX