00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef VCSN_ALGORITHMS_STANDARD_HXX
00019 # define VCSN_ALGORITHMS_STANDARD_HXX
00020
00021 # include <vaucanson/algorithms/standard.hh>
00022 # include <vaucanson/algorithms/internal/has_neighbour.hh>
00023
00024 # include <vaucanson/algorithms/sum.hh>
00025 # include <vaucanson/algorithms/accessible.hh>
00026 # include <vaucanson/automata/concept/automata_base.hh>
00027 # include <vaucanson/misc/usual_macros.hh>
00028
00029 # include <set>
00030
00031 namespace vcsn {
00032
00033
00034
00035
00036 template <class A_, typename Auto_>
00037 void
00038 do_in_standardize(const AutomataBase<A_>&, Auto_& a)
00039 {
00040 TIMER_SCOPED("standardize");
00041 AUTOMATON_TYPES(Auto_);
00042
00043 hstate_t i = a.add_state();
00044 std::list<htransition_t> transition_oi;
00045 series_set_elt_t final_series =
00046 algebra::zero_as<series_set_elt_value_t>::of(a.series());
00047
00048 for_all_const_initial_states(oi, a)
00049 {
00050 series_set_elt_t s = a.get_initial(*oi);
00051
00052
00053 transition_oi.clear();
00054 a.deltac(transition_oi, *oi, delta_kind::transitions());
00055 for_all_const_(std::list<htransition_t>, oil, transition_oi)
00056 {
00057 series_set_elt_t t = s * a.series_of(*oil);
00058 a.add_series_transition(i, a.dst_of(*oil), t);
00059 }
00060
00061 final_series += s * a.get_final(*oi);
00062 }
00063
00064
00065
00066
00067
00068 for (initial_iterator oi = a.initial().begin(), next = oi;
00069 oi != a.initial().end();
00070 oi = next)
00071 {
00072 ++next;
00073 if (!has_predecessors(a, *oi))
00074 a.del_state(*oi);
00075 }
00076 a.clear_initial();
00077 a.set_initial(i);
00078 a.set_final(i, final_series);
00079 }
00080
00081 template<typename A, typename T>
00082 void
00083 standardize(Element<A, T>& a)
00084 {
00085 do_in_standardize(a.structure(), a);
00086 }
00087
00088
00089
00090
00091
00092 template <typename A, typename lhs_t, typename rhs_t>
00093 void
00094 do_union_of_standard_here(const AutomataBase<A>&,
00095 lhs_t& lhs,
00096 const rhs_t& rhs)
00097 {
00098 precondition(is_standard(lhs));
00099 precondition(is_standard(rhs));
00100
00101 TIMER_SCOPED("union_of_standard");
00102 typedef std::list<typename lhs_t::htransition_t> edelta_ret_t;
00103
00104
00105 typename lhs_t::hstate_t new_i = *lhs.initial().begin();
00106 sum_here(lhs, rhs);
00107
00108
00109
00110 typename lhs_t::initial_support_t initial = lhs.initial();
00111
00112
00113 assertion (initial.size() == 2);
00114 typename lhs_t::initial_iterator i = initial.begin();
00115 typename lhs_t::hstate_t old_i = *i != new_i ? *i : *++i;
00116
00117 lhs.set_final(new_i,
00118 lhs.get_final(new_i) + lhs.get_final(old_i));
00119
00120
00121 edelta_ret_t dst;
00122 lhs.deltac(dst, old_i, delta_kind::transitions());
00123 for_all_const_(edelta_ret_t, d, dst)
00124 {
00125 lhs.add_transition(new_i,
00126 lhs.dst_of(*d),
00127 lhs.label_of(*d));
00128 lhs.del_transition(*d);
00129 }
00130 lhs.del_state(old_i);
00131 }
00132
00133 template<typename A, typename T, typename U>
00134 void
00135 union_of_standard_here(Element<A, T>& lhs, const Element<A, U>& rhs)
00136 {
00137
00138 do_union_of_standard_here(lhs.structure(), lhs, rhs);
00139 }
00140
00141 template<typename A, typename T, typename U>
00142 Element<A, T>
00143 union_of_standard(const Element<A, T>& lhs, const Element<A, U>& rhs)
00144 {
00145
00146 Element<A, T> ret(lhs);
00147 union_of_standard_here(ret, rhs);
00148 return ret;
00149 }
00150
00151
00152
00153
00154 template <typename A, typename auto_t>
00155 bool
00156 do_is_standard(const AutomataBase<A>&, const auto_t& a)
00157 {
00158 TIMER_SCOPED("is_standard");
00159 typedef typename auto_t::series_set_elt_value_t series_set_elt_value_t;
00160
00161
00162 if (a.initial().size() != 1)
00163 return false;
00164
00165
00166 typename auto_t::hstate_t s = *a.initial().begin();
00167 if (a.get_initial(s)
00168 != a.series().identity(SELECT(series_set_elt_value_t)))
00169 return false;
00170
00171
00172 return !has_predecessors(a, s);
00173 }
00174
00175 template<typename A, typename T>
00176 bool
00177 is_standard(const Element<A, T>& a)
00178 {
00179 return do_is_standard(a.structure(), a);
00180 }
00181
00182
00183
00184
00185 template <typename A, typename lhs_t, typename rhs_t>
00186 void
00187 do_concat_of_standard_here(const AutomataBase<A>&,
00188 lhs_t& lhs,
00189 const rhs_t& rhs)
00190 {
00191 precondition(is_standard(lhs));
00192 precondition(is_standard(rhs));
00193
00194 TIMER_SCOPED("concat_of_standard");
00195 AUTOMATON_TYPES(lhs_t);
00196 typedef std::map<hstate_t, hstate_t> map_t;
00197 typedef std::list<htransition_t> delta_ret_t;
00198
00199
00200
00201
00202 map_t map_h;
00203 delta_ret_t dst;
00204 hstate_t new_state;
00205
00206
00207 for (typename rhs_t::state_iterator s = rhs.states().begin();
00208 s != rhs.states().end();
00209 ++s)
00210 if (!rhs.is_initial(*s))
00211 {
00212 new_state = lhs.add_state();
00213 map_h[*s] = new_state;
00214 }
00215
00216
00217 for (typename rhs_t::state_iterator i = rhs.states().begin();
00218 i != rhs.states().end();
00219 ++i)
00220 if (!rhs.is_initial(*i))
00221 {
00222 dst.clear();
00223 rhs.deltac(dst, *i, delta_kind::transitions());
00224 for_all_const_(delta_ret_t, d, dst)
00225 lhs.add_transition(map_h[*i],
00226 map_h[rhs.dst_of(*d)],
00227 rhs.label_of(*d));
00228 }
00229
00230
00231 hstate_t rhs_i = *rhs.initial().begin();
00232 dst.clear();
00233 rhs.deltac(dst, rhs_i, delta_kind::transitions());
00234 for_all_const_final_states(f, lhs)
00235 {
00236 typename lhs_t::series_set_elt_t weight = lhs.get_final(*f);
00237 for_all_const_(delta_ret_t, d, dst)
00238 lhs.add_series_transition(*f,
00239 map_h[rhs.dst_of(*d)],
00240 weight * rhs.label_of(*d));
00241 }
00242
00243
00244
00245 typename lhs_t::series_set_elt_t rhs_iw = rhs.get_final(rhs_i);
00246 typename lhs_t::final_support_t support = lhs.final();
00247 for (typename lhs_t::final_iterator next = lhs.final().begin();
00248 next != lhs.final().end();)
00249 {
00250 typename lhs_t::final_iterator f = next;
00251 next++;
00252 lhs.set_final(*f, lhs.get_final(*f) * rhs_iw);
00253 }
00254
00255
00256 for_all_const_(map_t, nf, map_h)
00257 if (rhs.is_final(nf->first))
00258 lhs.set_final(nf->second, rhs.get_final(nf->first));
00259 }
00260
00261 template<typename A, typename T, typename U>
00262 void
00263 concat_of_standard_here(Element<A, T>& lhs, const Element<A, U>& rhs)
00264 {
00265
00266 do_concat_of_standard_here(lhs.structure(), lhs, rhs);
00267 }
00268
00269 template<typename A, typename T, typename U>
00270 Element<A, T>
00271 concat_of_standard(const Element<A, T>& lhs,
00272 const Element<A, U>& rhs)
00273 {
00274
00275 Element<A, T> ret(lhs);
00276 do_concat_of_standard_here(ret.structure(), ret, rhs);
00277 return ret;
00278 }
00279
00280
00281
00282
00283 template <typename A, typename auto_t>
00284 void
00285 do_star_of_standard_here(const AutomataBase<A>&, auto_t& a)
00286 {
00287 precondition(is_standard(a));
00288
00289 TIMER_SCOPED("star_of_standard");
00290 AUTOMATON_TYPES(auto_t);
00291 typedef std::list<htransition_t> edelta_ret_t;
00292
00293 edelta_ret_t dst;
00294 hstate_t new_i = *a.initial().begin();
00295 series_set_elt_t out_mult = a.get_final(new_i);
00296
00297 out_mult.star();
00298 a.deltac(dst, new_i, delta_kind::transitions());
00299 for_all_final_states(f, a)
00300 {
00301 if (*f != new_i)
00302 {
00303 series_set_elt_t f_mult = a.get_final(*f) * out_mult;
00304 a.set_final(*f, f_mult);
00305 for_all_const_(edelta_ret_t, d, dst)
00306 a.add_series_transition(*f, a.dst_of(*d), f_mult * a.label_of(*d));
00307 }
00308 }
00309 a.set_final(new_i, out_mult);
00310 }
00311
00312 template<typename A, typename T>
00313 void
00314 star_of_standard_here(Element<A, T>& a)
00315 {
00316 do_star_of_standard_here(a.structure(), a);
00317 }
00318
00319 template<typename A, typename T>
00320 Element<A, T>
00321 star_of_standard(const Element<A, T>& a)
00322 {
00323
00324 Element<A, T> ret(a);
00325 do_star_of_standard_here(ret.structure(), ret);
00326 return ret;
00327 }
00328
00329 }
00330
00331 #endif // ! VCSN_ALGORITHMS_STANDARD_HXX