00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_ACI_CANONICAL_HXX
00018 # define VCSN_ALGORITHMS_ACI_CANONICAL_HXX
00019
00020 # include <vaucanson/algorithms/aci_canonical.hh>
00021
00022 # include <vaucanson/algebra/concept/series_base.hh>
00023 # include <vaucanson/algebra/implementation/series/krat_exp_pattern.hh>
00024
00025 # include <set>
00026
00027 namespace vcsn
00028 {
00029
00038 template <class Series, class T, class Dispatch>
00039 struct KRatExpAciCanonical : algebra::KRatExpMatcher<
00040 KRatExpAciCanonical<Series, T, Dispatch>,
00041 T,
00042 std::set< Element<Series, T> >,
00043 Dispatch
00044 >
00045 {
00046 typedef Element<Series, T> exp_t;
00047 typedef std::set<exp_t> set_t;
00048 typedef std::set<exp_t> return_type;
00049 typedef typename set_t::iterator iterator_t;
00050 typedef KRatExpAciCanonical<Series, T, Dispatch> self_t;
00051 typedef typename Element<Series, T>::semiring_elt_t semiring_elt_t;
00052 typedef typename semiring_elt_t::value_t semiring_elt_value_t;
00053 typedef typename Element<Series, T>::monoid_elt_t monoid_elt_t;
00054 typedef typename monoid_elt_t::set_t monoid_t;
00055 typedef typename monoid_t::alphabet_t alphabet_t;
00056 typedef typename alphabet_t::letter_t letter_t;
00057 INHERIT_CONSTRUCTORS(self_t, T, semiring_elt_t, Dispatch);
00058
00059 KRatExpAciCanonical(const Element<Series, T>& exp) :
00060 exp_(exp)
00061 {}
00062
00063
00064 private:
00065 set_t apply_sum(set_t expset)
00066 {
00067 if (expset.size() != 1)
00068 {
00069 iterator_t i = expset.begin();
00070 exp_t res = *i;
00071 for (i++; i != expset.end(); ++i)
00072 {
00073 res += *i;
00074 }
00075 expset.clear();
00076 expset.insert(res);
00077 }
00078 return expset;
00079 }
00080
00081 set_t& put_in(set_t& s, exp_t e)
00082 {
00083 s.clear();
00084 s.insert(e);
00085 return s;
00086 }
00087
00088 public:
00089 exp_t set2exp(set_t expset)
00090 {
00091 expset = apply_sum(expset);
00092 return *expset.begin();
00093 }
00094
00095
00096 MATCH__(Product, lhs, rhs)
00097 {
00098 set_t lset = apply_sum(this->match(lhs));
00099 set_t rset = apply_sum(this->match(rhs));
00100 put_in(lset, *lset.begin() * *rset.begin());
00101 return lset;
00102 }
00103 END
00104
00105 MATCH__(Sum, lhs, rhs)
00106 {
00107 set_t lset = this->match(lhs);
00108 set_t rset = this->match(rhs);
00109 set_t res;
00110 merge(lset.begin(), lset.end(),
00111 rset.begin(), rset.end(),
00112 inserter(res, res.begin()));
00113 return res;
00114 }
00115 END
00116
00117 MATCH_(Star, e)
00118 {
00119 set_t cset = apply_sum(this->match(e));
00120 exp_t exp = *cset.begin();
00121 put_in(cset, exp.star());
00122 return cset;
00123 }
00124 END
00125
00126 MATCH__(LeftWeight, w, e)
00127 {
00128 set_t cset = apply_sum(this->match(e));
00129 put_in(cset, semiring_elt_t(w) * *cset.begin());
00130 return cset;
00131 }
00132 END
00133
00134 MATCH__(RightWeight, e, w)
00135 {
00136 set_t cset = apply_sum(this->match(e));
00137 put_in(cset, *cset.begin() * semiring_elt_t(w));
00138 return cset;
00139 }
00140 END
00141
00142 MATCH_(Constant, m)
00143 {
00144 set_t res;
00145 Element<Series, T> s (exp_.structure(), m);
00146 res.insert(s);
00147 return res;
00148 }
00149 END
00150
00151 MATCH(Zero)
00152 {
00153 set_t res;
00154 res.insert(exp_.structure().zero(SELECT(T)));
00155 return res;
00156 }
00157 END
00158
00159 MATCH(One)
00160 {
00161 set_t res;
00162 res.insert(exp_.structure().identity(SELECT(T)));
00163 return res;
00164 }
00165 END
00166
00167 private:
00168 Element<Series, T> exp_;
00169 };
00170
00171 template <typename S, typename SI>
00172 Element<S, SI>
00173 do_canonical(const algebra::SeriesBase<S>&, const Element<S, SI>& exp)
00174 {
00175 KRatExpAciCanonical<S, SI, algebra::DispatchFunction<SI> > matcher(exp);
00176 return matcher.set2exp(matcher.match(exp.value()));
00177 }
00178
00179 template <typename S, typename SI>
00180 Element<S, SI>
00181 canonical(const Element<S, SI>& exp)
00182 {
00183 BENCH_TASK_SCOPED("canonical");
00184 return do_canonical(exp.structure(), exp);
00185 }
00186
00187 }
00188
00189 #endif // ! VCSN_ALGORITHMS_ACI_CANONICAL_HXX