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 AI>
00037 void
00038 do_in_standardize(const AutomataBase<A>&, Element<A, AI>& a)
00039 {
00040 BENCH_TASK_SCOPED("standardize");
00041 typedef Element<A, AI> automaton_t;
00042 AUTOMATON_TYPES(automaton_t);
00043
00044 hstate_t i = a.add_state();
00045 std::list<htransition_t> transition_oi;
00046 series_set_elt_t final_series =
00047 algebra::zero_as<series_set_elt_value_t>::of(a.series());
00048
00049 for_all_const_initial_states(oi, a)
00050 {
00051 series_set_elt_t s = a.get_initial(*oi);
00052
00053
00054 transition_oi.clear();
00055 for (delta_iterator oil(a.value(), *oi);
00056 ! oil.done();
00057 oil.next())
00058 transition_oi.push_back(*oil);
00059 for_all_const_(std::list<htransition_t>, oil, transition_oi)
00060 {
00061 series_set_elt_t t = s * a.series_of(*oil);
00062 a.add_series_transition(i, a.dst_of(*oil), t);
00063 }
00064
00065 final_series += s * a.get_final(*oi);
00066 }
00067
00068
00069
00070
00071
00072 for (initial_iterator oi = a.initial().begin(), next = oi;
00073 oi != a.initial().end();
00074 oi = next)
00075 {
00076 ++next;
00077 if (!has_predecessors(a, *oi))
00078 a.del_state(*oi);
00079 }
00080 a.clear_initial();
00081 a.set_initial(i);
00082 a.set_final(i, final_series);
00083 }
00084
00085 template<typename A, typename AI>
00086 void
00087 standardize(Element<A, AI>& a)
00088 {
00089 do_in_standardize(a.structure(), a);
00090 }
00091
00092
00093
00094
00095
00096 template <typename A, typename AI1, typename AI2>
00097 void
00098 do_union_of_standard_here(const AutomataBase<A>&,
00099 Element<A, AI1>& lhs,
00100 const Element<A, AI2>& rhs)
00101 {
00102 precondition(is_standard(lhs));
00103 precondition(is_standard(rhs));
00104
00105 BENCH_TASK_SCOPED("union_of_standard");
00106
00107 typedef Element<A, AI1> lhs_t;
00108
00109
00110 typename lhs_t::hstate_t new_i = *lhs.initial().begin();
00111 sum_here(lhs, rhs);
00112
00113 assertion (lhs.initial().size() == 2);
00114 typename lhs_t::initial_iterator i = lhs.initial().begin();
00115 typename lhs_t::hstate_t old_i = *i != new_i ? *i : *++i;
00116
00117 union_of_standard_here_common(lhs.structure(), lhs, new_i, old_i);
00118 }
00119
00120
00121
00122
00123
00124 template<typename A, typename AI>
00125 void
00126 union_of_standard_here_common(const AutomataBase<A>&,
00127 Element<A, AI>& a,
00128 typename Element<A, AI>::hstate_t& new_i,
00129 typename Element<A, AI>::hstate_t& old_i)
00130 {
00131 typedef Element<A, AI> automaton_t;
00132 typedef typename automaton_t::htransition_t htransition_t;
00133 typedef typename automaton_t::delta_iterator delta_iterator_t;
00134 typedef std::list<htransition_t> delta_ret_t;
00135
00136
00137
00138 a.set_final(new_i,
00139 a.get_final(new_i) + a.get_final(old_i));
00140
00141
00142
00143
00144
00145
00146
00147 delta_ret_t dst;
00148
00149 for (delta_iterator_t i(a.value(), old_i);
00150 ! i.done();
00151 i.next())
00152 dst.push_back(*i);
00153
00154 for_all_const_(delta_ret_t, d, dst)
00155 {
00156 a.add_series_transition(new_i,
00157 a.dst_of(*d),
00158 a.series_of(*d));
00159 a.del_transition(*d);
00160 }
00161
00162 a.del_state(old_i);
00163 }
00164
00165 template<typename A, typename AI1, typename AI2>
00166 void
00167 union_of_standard_here(Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00168 {
00169 do_union_of_standard_here(lhs.structure(), lhs, rhs);
00170 }
00171
00172 template<typename A, typename AI1, typename AI2>
00173 Element<A, AI1>
00174 union_of_standard(const Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00175 {
00176 Element<A, AI1> ret(lhs);
00177 union_of_standard_here(ret, rhs);
00178 return ret;
00179 }
00180
00181
00182
00183
00184 template<typename A, typename AI>
00185 bool
00186 do_is_standard(const AutomataBase<A>&, const Element<A, AI>& a)
00187 {
00188 BENCH_TASK_SCOPED("is_standard");
00189 typedef Element<A, AI> automaton_t;
00190 typedef typename automaton_t::series_set_elt_value_t series_set_elt_value_t;
00191
00192
00193 if (a.initial().size() != 1)
00194 return false;
00195
00196
00197 typename automaton_t::hstate_t s = *a.initial().begin();
00198 if (a.get_initial(s)
00199 != a.series().identity(SELECT(series_set_elt_value_t)))
00200 return false;
00201
00202
00203 return !has_predecessors(a, s);
00204 }
00205
00206 template<typename A, typename AI>
00207 bool
00208 is_standard(const Element<A, AI>& a)
00209 {
00210 return do_is_standard(a.structure(), a);
00211 }
00212
00213
00214
00215
00216 template <typename A, typename AI1, typename AI2>
00217 void
00218 do_concat_of_standard_here(const AutomataBase<A>&,
00219 Element<A, AI1>& lhs,
00220 const Element<A, AI2>& rhs)
00221 {
00222 precondition(is_standard(lhs));
00223 precondition(is_standard(rhs));
00224
00225 BENCH_TASK_SCOPED("concat_of_standard");
00226 typedef Element<A, AI1> lhs_t;
00227 typedef Element<A, AI2> rhs_t;
00228 typedef typename lhs_t::hstate_t l_hstate_t;
00229 typedef typename rhs_t::hstate_t r_hstate_t;
00230 typedef std::map<l_hstate_t, r_hstate_t> map_t;
00231
00232
00233
00234
00235 map_t map_h;
00236 l_hstate_t new_state;
00237
00238
00239 for (typename rhs_t::state_iterator s = rhs.states().begin();
00240 s != rhs.states().end();
00241 ++s)
00242 if (!rhs.is_initial(*s))
00243 {
00244 new_state = lhs.add_state();
00245 map_h[*s] = new_state;
00246 }
00247
00248
00249 for (typename rhs_t::state_iterator i = rhs.states().begin();
00250 i != rhs.states().end();
00251 ++i)
00252 if (!rhs.is_initial(*i))
00253 {
00254 for (typename rhs_t::delta_iterator d(rhs.value(), *i);
00255 ! d.done();
00256 d.next())
00257 lhs.add_transition(map_h[*i],
00258 map_h[rhs.dst_of(*d)],
00259 rhs.label_of(*d));
00260 }
00261
00262
00263 r_hstate_t rhs_i = *rhs.initial().begin();
00264
00265 concat_of_standard_here_common(lhs.structure(),
00266 lhs,
00267 rhs,
00268 rhs_i,
00269 lhs.final().begin(),
00270 lhs.final().end(),
00271 map_h);
00272
00273
00274 for_all_const_(map_t, nf, map_h)
00275 if (rhs.is_final(nf->first))
00276 lhs.set_final(nf->second, rhs.get_final(nf->first));
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286 template<typename A, typename AI1, typename AI2, typename T1, typename T2>
00287 void
00288 concat_of_standard_here_common(const AutomataBase<A>&,
00289 Element<A, AI1>& lhs,
00290 const Element<A, AI2>& rhs,
00291 typename Element<A, AI2>::hstate_t& rhs_i,
00292 const T1& lhs_finals_b,
00293 const T1& lhs_finals_e,
00294 T2& accessor)
00295 {
00296 typedef Element<A, AI1> lhs_t;
00297 typedef Element<A, AI2> rhs_t;
00298 typedef T1 lhs_final_it_t;
00299 typedef typename rhs_t::delta_iterator delta_iterator_t;
00300 typedef typename lhs_t::htransition_t htransition_t;
00301 typedef std::list<htransition_t> delta_ret_t;
00302
00303 delta_ret_t dst;
00304
00305 for (delta_iterator_t i(rhs.value(), rhs_i);
00306 ! i.done();
00307 i.next())
00308 dst.push_back(*i);
00309
00310
00311 for (lhs_final_it_t f = lhs_finals_b;
00312 f != lhs_finals_e;
00313 ++f)
00314 {
00315 typename lhs_t::series_set_elt_t weight = lhs.get_final(*f);
00316
00317 for_all_const_(delta_ret_t, d, dst)
00318 lhs.add_series_transition(*f,
00319 accessor[rhs.dst_of(*d)],
00320 weight * rhs.label_of(*d));
00321 }
00322
00323
00324
00325 typename lhs_t::series_set_elt_t rhs_iw = rhs.get_final(rhs_i);
00326
00327 for (lhs_final_it_t next = lhs_finals_b;
00328 next != lhs_finals_e;)
00329 {
00330 lhs_final_it_t f = next;
00331 next++;
00332 lhs.set_final(*f, lhs.get_final(*f) * rhs_iw);
00333 }
00334 }
00335
00336 template<typename A, typename AI1, typename AI2>
00337 void
00338 concat_of_standard_here(Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00339 {
00340 do_concat_of_standard_here(lhs.structure(), lhs, rhs);
00341 }
00342
00343 template<typename A, typename AI1, typename AI2>
00344 Element<A, AI1>
00345 concat_of_standard(const Element<A, AI1>& lhs,
00346 const Element<A, AI2>& rhs)
00347 {
00348 Element<A, AI1> ret(lhs);
00349 do_concat_of_standard_here(ret.structure(), ret, rhs);
00350 return ret;
00351 }
00352
00353
00354
00355
00356 template <typename A, typename AI>
00357 void
00358 do_star_of_standard_here(const AutomataBase<A>&, Element<A, AI>& a)
00359 {
00360 precondition(is_standard(a));
00361
00362 BENCH_TASK_SCOPED("star_of_standard");
00363
00364 assertion (a.initial().size() == 1);
00365 typename Element<A, AI>::hstate_t new_i = *a.initial().begin();
00366 star_of_standard_here_common(a.structure(), a, new_i);
00367 }
00368
00369
00370 template<typename A, typename AI>
00371 void
00372 star_of_standard_here_common(const AutomataBase<A>&,
00373 Element<A, AI>& a,
00374 typename Element<A, AI>::hstate_t& new_i)
00375 {
00376 typedef Element<A, AI> automaton_t;
00377 AUTOMATON_TYPES(automaton_t);
00378 typedef std::list<htransition_t> delta_ret_t;
00379
00380
00381
00382
00383
00384
00385
00386 series_set_elt_t out_mult = a.get_final(new_i);
00387
00388 out_mult.star();
00389
00390 delta_ret_t dst;
00391
00392 for (delta_iterator i(a.value(), new_i);
00393 ! i.done();
00394 i.next())
00395 dst.push_back(*i);
00396
00397 for_all_final_states(f, a)
00398 {
00399 if (*f != new_i)
00400 {
00401 series_set_elt_t f_mult = a.get_final(*f) * out_mult;
00402 a.set_final(*f, f_mult);
00403
00404 for_all_const_(delta_ret_t, d, dst)
00405 a.add_series_transition(*f, a.dst_of(*d), f_mult * a.label_of(*d));
00406 }
00407 }
00408 a.set_final(new_i, out_mult);
00409 }
00410
00411 template<typename A, typename AI>
00412 void
00413 star_of_standard_here(Element<A, AI>& a)
00414 {
00415 do_star_of_standard_here(a.structure(), a);
00416 }
00417
00418 template<typename A, typename AI>
00419 Element<A, AI>
00420 star_of_standard(const Element<A, AI>& a)
00421 {
00422 Element<A, AI> ret(a);
00423 do_star_of_standard_here(ret.structure(), ret);
00424 return ret;
00425 }
00426
00427 }
00428
00429 #endif // ! VCSN_ALGORITHMS_STANDARD_HXX