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