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/one_eps_closure.hh>
00023 # include <vaucanson/algorithms/internal/has_neighbour.hh>
00024 # include <vaucanson/algorithms/internal/build_pattern.hh>
00025
00026 # include <vaucanson/algorithms/accessible.hh>
00027 # include <vaucanson/automata/concept/automata_base.hh>
00028 # include <vaucanson/automata/concept/automata.hh>
00029 # include <vaucanson/misc/usual_macros.hh>
00030
00031 # include <set>
00032
00033 namespace vcsn {
00034
00035
00036
00037
00038
00039 template<typename HSTATE, typename WEIGHT>
00040 struct basic_sptr
00041 {
00042 private:
00043 const HSTATE& src_;
00044 const HSTATE& dst_;
00045 const WEIGHT& weight_;
00046
00047 public:
00048 basic_sptr(const HSTATE& src, const HSTATE& dst, const WEIGHT& weight) :
00049 src_(src), dst_(dst), weight_(weight) {}
00050
00051 HSTATE src() const {
00052 return src_;
00053 }
00054
00055 HSTATE dst() const {
00056 return dst_;
00057 }
00058
00059 WEIGHT weight() const {
00060 return weight_;
00061 }
00062 };
00063
00064
00065
00066
00067
00068
00069 template <typename A, typename AI1, typename AI2>
00070 void
00071 do_union_here(const AutomataBase<A>&,
00072 Element<A, AI1>& lhs,
00073 const Element<A, AI2>& rhs)
00074 {
00075 typedef Element<A, AI1> lhs_t;
00076 AUTOMATON_TYPES(lhs_t);
00077 typedef Element<A, AI2> rhs_t;
00078 typedef typename rhs_t::hstate_t r_hstate_t;
00079
00080 std::map<r_hstate_t, hstate_t> states_map;
00081
00082
00083 for_all_states(it, rhs)
00084 {
00085 hstate_t new_state = lhs.add_state();
00086 states_map[*it] = new_state;
00087
00088 lhs.set_initial(new_state, rhs.get_initial(*it));
00089 lhs.set_final(new_state, rhs.get_final(*it));
00090 }
00091
00092
00093 for_all_transitions(it, rhs)
00094 {
00095 lhs.add_transition(states_map[rhs.src_of(*it)],
00096 states_map[rhs.dst_of(*it)],
00097 rhs.label_of(*it));
00098 }
00099 }
00100
00101
00102 template<typename A, typename AI1, typename AI2>
00103 void
00104 union_here(Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00105 {
00106 do_union_here(lhs.structure(), lhs, rhs);
00107 }
00108
00109
00110 template<typename A, typename AI1, typename AI2>
00111 Element<A, AI1>
00112 union_(const Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00113 {
00114 Element<A, AI1> ret(lhs);
00115 do_union_here(ret.structure(), ret, rhs);
00116 return ret;
00117 }
00118
00119
00120
00121 template <typename A, typename AI1, typename AI2>
00122 void
00123 marked_union_here(const AutomataBase<A>&,
00124 Element<A, AI1>& lhs,
00125 const Element<A, AI2>& rhs,
00126 const typename Element<A, AI1>::hstate_t& lhs_stt,
00127 typename Element<A, AI1>::hstate_t& mrk_stt,
00128 const typename Element<A, AI2>::hstate_t& rhs_stt)
00129 {
00130 typedef Element<A, AI1> lhs_t;
00131 AUTOMATON_TYPES(lhs_t);
00132 typedef Element<A, AI2> rhs_t;
00133 typedef typename rhs_t::hstate_t r_hstate_t;
00134 std::map<r_hstate_t, hstate_t> states_map;
00135
00136
00137 for_all_states(it, rhs)
00138 {
00139 hstate_t new_state = lhs.add_state();
00140 states_map[*it] = new_state;
00141
00142 lhs.set_initial(new_state, rhs.get_initial(*it));
00143 lhs.set_final(new_state, rhs.get_final(*it));
00144 }
00145 mrk_stt = states_map[rhs_stt];
00146
00147
00148 for_all_transitions(it, rhs)
00149 {
00150 lhs.add_transition(states_map[rhs.src_of(*it)],
00151 states_map[rhs.dst_of(*it)],
00152 rhs.label_of(*it));
00153 }
00154 }
00155
00156
00157
00158
00159 template<typename A, typename AI>
00160 bool
00161 do_is_standard(const AutomataBase<A>&, const Element<A, AI>& a)
00162 {
00163 BENCH_TASK_SCOPED("is_standard");
00164 typedef Element<A, AI> automaton_t;
00165 typedef typename automaton_t::series_set_elt_value_t series_set_elt_value_t;
00166
00167
00168 if (a.initial().size() != 1)
00169 return false;
00170
00171
00172 typename automaton_t::hstate_t s = *a.initial().begin();
00173 if (a.get_initial(s)
00174 != a.series().identity(SELECT(series_set_elt_value_t)))
00175 return false;
00176
00177
00178 return !has_predecessors(a, s);
00179 }
00180
00181 template<typename A, typename AI>
00182 bool
00183 is_standard(const Element<A, AI>& a)
00184 {
00185 return do_is_standard(a.structure(), a);
00186 }
00187
00188
00189
00190
00191
00192 template<typename S, typename AI>
00193 void
00194 do_standardize(const AutomataBase<S>&, Element<S, AI>& a)
00195 {
00196 BENCH_TASK_SCOPED("standardize");
00197 typedef Element<S, AI> automaton_t;
00198 AUTOMATON_TYPES(automaton_t);
00199 typedef basic_sptr<hstate_t, series_set_elt_t> sptr_t;
00200 typedef typename std::list<hstate_t> stt_lst_t;
00201
00202 stt_lst_t stt_list;
00203 series_set_elt_t fin_wgt =
00204 algebra::zero_as<series_set_elt_value_t>::of(a.series());
00205
00206 if (is_standard(a)) return;
00207
00208 hstate_t i = a.add_state();
00209
00210
00211 for_all_initial_states(it, a) stt_list.push_back(*it);
00212
00213 for_all(typename stt_lst_t, it, stt_list)
00214 {
00215 hstate_t ini_stt = *it;
00216 series_set_elt_t ini_wgt = a.get_initial(ini_stt);
00217
00218
00219 sptr_t t(i, ini_stt, ini_wgt);
00220 one_eps_closure(a, t, misc::backward);
00221
00222 a.unset_initial(ini_stt);
00223
00224 if (!has_predecessors(a, ini_stt))
00225 a.del_state(ini_stt);
00226 }
00227
00228 a.set_initial(i);
00229
00230 return;
00231 }
00232
00233
00234 template<typename A, typename AI>
00235 void
00236 standardize(Element<A, AI>& a)
00237 {
00238 do_standardize(a.structure(), a);
00239 }
00240
00241
00242
00243
00244
00245 template <typename A, typename AI>
00246 void
00247 sum_of_standard_inside(const AutomataBase<A>&, Element<A, AI>& aut,
00248 const typename Element<A, AI>::hstate_t& aut_stt,
00249 typename Element<A, AI>::hstate_t& mrk_stt)
00250 {
00251 typedef Element<A, AI> automaton_t; AUTOMATON_TYPES(automaton_t);
00252 typedef series_set_elt_t weight_t;
00253 typedef basic_sptr<hstate_t, weight_t> sptr_t;
00254
00255 weight_t unit = aut.series().identity(SELECT(series_set_elt_value_t));
00256
00257 sptr_t t(aut_stt, mrk_stt, unit);
00258 one_eps_closure(aut, t, misc::backward);
00259 aut.del_state(mrk_stt);
00260 }
00261
00262
00263 template <typename A, typename AI1, typename AI2>
00264 void
00265 do_sum_of_standard_here(const AutomataBase<A>&,
00266 Element<A, AI1>& lhs,
00267 const Element<A, AI2>& rhs)
00268 {
00269 BENCH_TASK_SCOPED("sum_of_standard");
00270
00271 typedef Element<A, AI1> lhs_t;
00272 AUTOMATON_TYPES(lhs_t);
00273 typedef Element<A, AI2> rhs_t;
00274 typedef typename rhs_t::hstate_t r_hstate_t;
00275
00276 hstate_t mrk_stt;
00277
00278
00279 hstate_t lhs_stt = *lhs.initial().begin();
00280 r_hstate_t rhs_stt = *rhs.initial().begin();
00281
00282 marked_union_here(lhs.structure(), lhs, rhs, lhs_stt, mrk_stt, rhs_stt);
00283
00284 sum_of_standard_inside(lhs.structure(), lhs, lhs_stt, mrk_stt);
00285 }
00286
00287
00288 template<typename A, typename AI1, typename AI2>
00289 void
00290 sum_of_standard_here(Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00291 {
00292 precondition(is_standard(lhs));
00293 precondition(is_standard(rhs));
00294 do_sum_of_standard_here(lhs.structure(), lhs, rhs);
00295 }
00296
00297 template<typename A, typename AI1, typename AI2>
00298 Element<A, AI1>
00299 sum_of_standard(const Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00300 {
00301 precondition(is_standard(lhs));
00302 precondition(is_standard(rhs));
00303 Element<A, AI1> ret(lhs);
00304 sum_of_standard_here(ret, rhs);
00305 return ret;
00306 }
00307
00308
00309
00310
00311
00312
00313 template <typename A, typename AI>
00314 void
00315 concat_of_standard_inside(const AutomataBase<A>&, Element<A, AI>& aut,
00316 typename std::list<typename Element<A, AI>::hstate_t>& stt_list,
00317 typename Element<A, AI>::hstate_t& mrk_stt)
00318 {
00319 typedef Element<A, AI> aut_t;
00320 AUTOMATON_TYPES(aut_t);
00321 typedef series_set_elt_t weight_t;
00322 typedef typename std::list<hstate_t> stt_lst_t;
00323 typedef basic_sptr<hstate_t, weight_t> sptr_t;
00324
00325 weight_t mrk_wgt = aut.get_final(mrk_stt);
00326
00327 for_all(typename stt_lst_t, it, stt_list)
00328 {
00329 hstate_t fin_stt = *it;
00330 weight_t fin_wgt = aut.get_final(fin_stt);
00331 aut.unset_final(fin_stt);
00332 sptr_t t(fin_stt, mrk_stt, fin_wgt);
00333 one_eps_closure(aut, t, misc::backward);
00334 }
00335 aut.del_state(mrk_stt);
00336 }
00337
00338
00339 template <typename A, typename AI1, typename AI2>
00340 void
00341 do_concat_of_standard_here(const AutomataBase<A>&,
00342 Element<A, AI1>& lhs,
00343 const Element<A, AI2>& rhs)
00344 {
00345 BENCH_TASK_SCOPED("concat_of_standard");
00346
00347 typedef Element<A, AI1> lhs_t;
00348 AUTOMATON_TYPES(lhs_t);
00349 typedef std::list<hstate_t> stt_lst_t;
00350 typedef Element<A, AI2> rhs_t;
00351 typedef typename rhs_t::hstate_t r_hstate_t;
00352
00353
00354 stt_lst_t stt_list;
00355 for_all_final_states(it, lhs) stt_list.push_back(*it);
00356
00357
00358 hstate_t mrk_stt;
00359 hstate_t lhs_stt = *lhs.initial().begin();
00360 r_hstate_t rhs_stt = *rhs.initial().begin();
00361 marked_union_here(lhs.structure(), lhs, rhs, lhs_stt, mrk_stt, rhs_stt);
00362
00363 concat_of_standard_inside(lhs.structure(), lhs, stt_list, mrk_stt);
00364 }
00365
00366
00367 template<typename A, typename AI1, typename AI2>
00368 void
00369 concat_of_standard_here(Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00370 {
00371 precondition(is_standard(lhs));
00372 precondition(is_standard(rhs));
00373 do_concat_of_standard_here(lhs.structure(), lhs, rhs);
00374 }
00375
00376 template<typename A, typename AI1, typename AI2>
00377 Element<A, AI1>
00378 concat_of_standard(const Element<A, AI1>& lhs,
00379 const Element<A, AI2>& rhs)
00380 {
00381 precondition(is_standard(lhs));
00382 precondition(is_standard(rhs));
00383 Element<A, AI1> ret(lhs);
00384 do_concat_of_standard_here(ret.structure(), ret, rhs);
00385 return ret;
00386 }
00387
00388
00389
00390
00391
00392
00393 template <typename A, typename AI>
00394 void
00395 left_ext_mult_of_standard_inside(const AutomataBase<A>&,
00396 Element<A, AI>& aut,
00397 const typename Element<A, AI>::hstate_t& ini_stt,
00398 const typename Element<A, AI>::series_set_elt_t& k)
00399 {
00400 typedef Element<A, AI> automaton_t; AUTOMATON_TYPES(automaton_t);
00401 typedef series_set_elt_t weight_t;
00402 typedef typename std::list<htransition_t> trn_lst_t;
00403
00404 weight_t zero(aut.series().zero_);
00405 trn_lst_t ini_out_list;
00406
00407
00408 for (delta_iterator it(aut.value(), ini_stt); !it.done(); it.next())
00409 ini_out_list.push_back(*it);
00410
00411
00412
00413
00414
00415 if (k == zero)
00416 {
00417
00418 for_all(typename trn_lst_t, it, ini_out_list)
00419 aut.del_transition(*it);
00420
00421 aut.unset_final(ini_stt);
00422 }
00423
00424 else
00425 {
00426 for_all(typename trn_lst_t, it, ini_out_list)
00427 {
00428 hstate_t dest = aut.dst_of(*it);
00429 weight_t wgt = k * aut.series_of(*it);
00430 aut.del_transition(*it);
00431 aut.add_series_transition(ini_stt, dest, wgt);
00432 }
00433
00434 aut.set_final(ini_stt, k * aut.get_final(ini_stt));
00435 }
00436 }
00437
00438 template <typename A, typename AI>
00439 void
00440 left_mult_of_standard_here(Element<A, AI>& aut,
00441 const typename Element<A, AI>::series_set_elt_t& k)
00442 {
00443 precondition(is_standard(aut));
00444 left_ext_mult_of_standard_inside(aut.structure(), aut,
00445 *aut.initial().begin(), k);
00446 }
00447
00448
00449
00450
00451
00452 template <typename A, typename AI>
00453 void
00454 right_ext_mult_of_standard_inside
00455 (const AutomataBase<A>&, Element<A, AI>& aut,
00456 typename std::list<typename Element<A, AI>::hstate_t>& stt_list,
00457 const typename Element<A, AI>::series_set_elt_t& k)
00458 {
00459 typedef Element<A, AI> automaton_t; AUTOMATON_TYPES(automaton_t);
00460 typedef typename std::list<hstate_t> stt_lst_t;
00461
00462
00463
00464 for_all(typename stt_lst_t, it, stt_list)
00465 aut.set_final(*it, aut.get_final(*it) * k);
00466 }
00467
00468 template <typename A, typename AI>
00469 void
00470 right_mult_of_standard_here(Element<A, AI>& aut,
00471 const typename Element<A, AI>::series_set_elt_t& k)
00472 {
00473 typedef Element<A, AI> automaton_t;
00474 AUTOMATON_TYPES(automaton_t);
00475
00476 precondition(is_standard(aut));
00477 std::list<hstate_t> finals;
00478 for_all_final_states(it, aut) finals.push_back(*it);
00479
00480 right_ext_mult_of_standard_inside(aut.structure(), aut,
00481 finals, k);
00482 }
00483
00484
00485
00486
00487
00488 template <typename A, typename AI>
00489 void
00490 star_of_standard_inside(const AutomataBase<A>&, Element<A, AI>& aut,
00491 const typename Element<A, AI>::hstate_t& ini_stt,
00492 typename std::list<typename Element<A, AI>::hstate_t>& stt_list)
00493 {
00494 typedef Element<A, AI> automaton_t; AUTOMATON_TYPES(automaton_t);
00495 typedef series_set_elt_t weight_t;
00496 typedef typename std::list<hstate_t> stt_lst_t;
00497 typedef basic_sptr<hstate_t, weight_t> sptr_t;
00498 weight_t unit = aut.series().identity(SELECT(series_set_elt_value_t));
00499
00500
00501
00502 weight_t fin_wgt = aut.get_final(ini_stt); fin_wgt.star();
00503
00504
00505 aut.set_final(ini_stt, unit);
00506 left_ext_mult_of_standard_inside(aut.structure(), aut, ini_stt, fin_wgt);
00507
00508
00509
00510 for_all(typename stt_lst_t, it, stt_list)
00511 {
00512 hstate_t crn_stt = *it;
00513 weight_t crn_fin_wgt = aut.get_final(crn_stt);
00514 aut.unset_final(crn_stt);
00515
00516 sptr_t t(crn_stt, ini_stt, crn_fin_wgt);
00517 one_eps_closure(aut, t, misc::backward);
00518 }
00519 }
00520
00521
00522 template <typename A, typename AI>
00523 void
00524 do_star_of_standard_here(const AutomataBase<A>&, Element<A, AI>& a)
00525 {
00526 BENCH_TASK_SCOPED("star_of_standard");
00527 typedef Element<A, AI> automaton_t; AUTOMATON_TYPES(automaton_t);
00528 typedef series_set_elt_t weight_t;
00529 typedef std::list<hstate_t> stt_lst_t;
00530
00531 hstate_t ini_stt = *a.initial().begin();
00532 weight_t fin_wgt = a.get_final(ini_stt);
00533
00534 precondition(fin_wgt.starable());
00535
00536 stt_lst_t stt_list;
00537 for_all_final_states(it, a)
00538 if (*it != ini_stt)
00539 stt_list.push_back(*it);
00540
00541 star_of_standard_inside(a.structure(), a, ini_stt, stt_list);
00542 }
00543
00544 template<typename A, typename AI>
00545 void
00546 star_of_standard_here(Element<A, AI>& a)
00547 {
00548 precondition(is_standard(a));
00549 do_star_of_standard_here(a.structure(), a);
00550 }
00551
00552 template<typename A, typename AI>
00553 Element<A, AI>
00554 star_of_standard(const Element<A, AI>& a)
00555 {
00556 precondition(is_standard(a));
00557 Element<A, AI> ret(a);
00558 do_star_of_standard_here(ret.structure(), ret);
00559 return ret;
00560 }
00561
00562 }
00563
00564 #endif // ! VCSN_ALGORITHMS_STANDARD_HXX