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