00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_DERIVED_TERM_AUTOMATON_HXX
00018 # define VCSN_ALGORITHMS_DERIVED_TERM_AUTOMATON_HXX
00019
00020 # include <vaucanson/algorithms/derived_term_automaton.hh>
00021
00022 # include <vaucanson/algorithms/internal/build_pattern.hh>
00023 # include <vaucanson/algorithms/internal/partial_rat_exp.hh>
00024 # include <vaucanson/algorithms/internal/partial_rat_exp_constant_term.hh>
00025 # include <vaucanson/algorithms/internal/partial_rat_exp_derivation.hh>
00026
00027 # include <vaucanson/algorithms/krat_exp_realtime.hh>
00028 # include <vaucanson/misc/usual_macros.hh>
00029 # include <vaucanson/algorithms/initial_derivation.hh>
00030
00031 # ifdef DEBUG
00032
00033 namespace std
00034 {
00035 template <typename T>
00036 std::ostream& operator << (std::ostream& o, const std::list<T>& l)
00037 {
00038 typename std::list<T>::const_iterator i = l.begin();
00039
00040 o << '{';
00041 if (i != l.end())
00042 {
00043 o << *i;
00044 for (i++; i != l.end(); ++i)
00045 o << ", " << *i;
00046 }
00047 return o << '}';
00048 }
00049 }
00050
00051 # define DERIVATES_TRACE_DEBUG(undef, e, l, s) \
00052 if (!undef) \
00053 { \
00054 std::cout << "Deriv " \
00055 << e \
00056 << " by " \
00057 << l \
00058 << " =" \
00059 << std::endl; \
00060 std::cout << s << std::endl; \
00061 std::cout << std::endl; \
00062 }
00063
00064 # else
00065
00066 # define DERIVATES_TRACE_DEBUG(undef, e, l, s)
00067
00068 # endif
00069
00070 namespace vcsn {
00071
00072 using namespace algorithm_patterns;
00073
00074
00075
00076 template <typename T_auto, typename S, typename T>
00077 struct DerivativesAlgo : public IncAutomataConstructor <
00078 DerivativesAlgo<T_auto, S, T>,
00079 T_auto,
00080 PartialExp<S, T> >
00081 {
00082 typedef PartialExp<S, T> exp_t;
00083 typedef std::list<exp_t> exp_list_t;
00084 typedef typename exp_list_t::iterator exp_list_iterator;
00085 AUTOMATON_TYPES(T_auto);
00086 AUTOMATON_FREEMONOID_TYPES(T_auto);
00087
00088
00089
00090 DerivativesAlgo(const series_set_t& series, const Element<S, T>& exp):
00091 IncAutomataConstructor<DerivativesAlgo, T_auto, PartialExp<S, T> >
00092 (series, prat_exp_convert(exp)),
00093 undefined(false)
00094 {}
00095
00096
00097
00098
00099 DerivativesAlgo(const series_set_t& series,
00100 const std::list<Element<S, T> >& listexp):
00101 IncAutomataConstructor<DerivativesAlgo, T_auto, PartialExp<S, T> >
00102 (series, prat_exp_convert(listexp)),
00103 undefined(false)
00104 {}
00105
00106
00107 void on_state(const PartialExp<S, T>& e)
00108 {
00109 alphabet_t alpha = this->get()->series().monoid().alphabet();
00110
00111
00112
00113 std::pair<semiring_elt_t, bool> c_term = constant_term(e);
00114 if (!c_term.second)
00115 undefined = true;
00116 if (c_term.first !=
00117 e.exp_structure().semiring().zero(SELECT(semiring_elt_value_t)))
00118 set_final(series_set_elt_t (e.exp_structure(), c_term.first));
00119
00120
00121
00122 for (alphabet_iterator a = alpha.begin(); a != alpha.end(); ++a)
00123 {
00124 std::pair<std::list<PartialExp<S, T> >, bool>
00125 s = prat_exp_derivate(e, *a);
00126 if (!s.second)
00127 undefined = true;
00128 DERIVATES_TRACE_DEBUG(undefined, e, *a, s.first);
00129 for (exp_list_iterator i = s.first.begin(); i != s.first.end(); ++i)
00130 {
00131 PartialExp<S, T> p_exp = *i;
00132 series_set_elt_t s_elt (e.exp_structure(),
00133 monoid_elt_t(e.exp_structure().monoid(), *a));
00134 s_elt = p_exp.begin().semiring_elt() * s_elt;
00135 p_exp.begin().semiring_elt() =
00136 e.exp_structure().semiring().identity(SELECT(semiring_elt_value_t));
00137 link_to(p_exp, s_elt);
00138 }
00139 }
00140 }
00141
00142 bool undefined;
00143 };
00144
00145 template<typename T_auto, typename S, typename T>
00146 T_auto*
00147 do_derived_term_automaton(const T_auto& out,
00148 const Element<S, T>& kexp)
00149 {
00150 Element<S, T> exp = realtime(kexp);
00151 DerivativesAlgo<T_auto, S, T> derivatives_algo(out.series(), exp);
00152 derivatives_algo.run();
00153 if (derivatives_algo.undefined)
00154 {
00155 delete derivatives_algo.get();
00156 return NULL;
00157 }
00158 else
00159 return derivatives_algo.get();
00160 }
00161
00162 template<typename A, typename T, typename Exp>
00163 void
00164 derived_term_automaton(Element<A, T>& out, const Exp& kexp)
00165 {
00166 Element<A, T>* result = do_derived_term_automaton(out, kexp);
00167 if (result != NULL)
00168 out = *result;
00169 }
00170
00171 template<typename A, typename T, typename Exp>
00172 Element<A, T>
00173 derived_term_automaton(const Exp& kexp)
00174 {
00175 A a_structure(kexp.structure());
00176 Element<A, T> out (a_structure);
00177 Element<A, T>* result = do_derived_term_automaton(out, kexp);
00178 if (result != NULL)
00179 out = *result;
00180 return out;
00181 }
00182
00183
00184 template<typename T_auto, typename S, typename T>
00185 T_auto*
00186 do_broken_derived_term_automaton(const T_auto& out,
00187 const Element<S, T>& kexp)
00188 {
00189 Element<S, T> exp = realtime(kexp);
00190 KRatExpInitialDerivation< S, T, algebra::DispatchFunction<T> >
00191 matcher(exp);
00192 std::list< Element<S, T> > listexp = matcher.match(exp.value());
00193 DerivativesAlgo<T_auto, S, T> derivatives_algo(out.series(),
00194 listexp);
00195 derivatives_algo.run();
00196 if (derivatives_algo.undefined)
00197 {
00198 delete derivatives_algo.get();
00199 return NULL;
00200 }
00201 else
00202 return derivatives_algo.get();
00203 }
00204
00205 template<typename A, typename T, typename Exp>
00206 void
00207 broken_derived_term_automaton(Element<A, T>& out, const Exp& kexp)
00208 {
00209 Element<A, T>* result = do_broken_derived_term_automaton(out, kexp);
00210 if (result != NULL)
00211 out = *result;
00212 }
00213
00214 template<typename A, typename T, typename Exp>
00215 Element<A, T>
00216 broken_derived_term_automaton(const Exp& kexp)
00217 {
00218 A a_structure(kexp.structure());
00219 Element<A, T> out (a_structure);
00220 Element<A, T>* result = do_broken_derived_term_automaton(out, kexp);
00221 if (result != NULL)
00222 out = *result;
00223 return out;
00224 }
00225
00226
00227
00228 }
00229
00230 #endif // ! VCSN_ALGORITHMS_DERIVED_TERM_AUTOMATON_HXX