00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_EPS_REMOVAL_HXX
00018 # define VCSN_ALGORITHMS_EPS_REMOVAL_HXX
00019
00020 # include <vaucanson/algorithms/eps_removal.hh>
00021
00022 # include <vaucanson/automata/concept/automata_base.hh>
00023 # include <vaucanson/algebra/concept/freemonoid_product.hh>
00024 # include <vaucanson/misc/usual_macros.hh>
00025
00026 # include <list>
00027 # include <map>
00028 # include <utility>
00029
00030 namespace vcsn {
00031
00032
00033 template <class A, typename M, typename AI>
00034 bool
00035 do_is_proper(const AutomataBase<A>&, const M&, const Element<A, AI>& a)
00036 {
00037 BENCH_TASK_SCOPED("is_proper (automaton)");
00038 typedef Element<A, AI> automaton_t;
00039 AUTOMATON_TYPES(automaton_t);
00040
00041 for_all_const_transitions(e, a)
00042 {
00043
00044
00045
00046 series_set_elt_t label = a.series_of(*e);
00047 for_all_const_(series_set_elt_t::support_t, it, label.supp())
00048 if ((*it).empty())
00049 return false;
00050 }
00051 return true;
00052 }
00053
00054
00055 template <class A, typename F, typename S, typename AI>
00056 bool
00057 do_is_proper(const AutomataBase<A>&,
00058 const algebra::FreeMonoidProduct<F, S>&,
00059 const Element<A, AI>& a)
00060 {
00061 BENCH_TASK_SCOPED("is_proper (FMP)");
00062 typedef Element<A, AI> automaton_t;
00063 AUTOMATON_TYPES(automaton_t);
00064
00065 for_all_const_transitions(e, a)
00066 {
00067 series_set_elt_t label = a.series_of(*e);
00068 for_all_const_(series_set_elt_t::support_t, it, label.supp())
00069 if ((*it).first.empty() && (*it).second.empty())
00070 return false;
00071 }
00072 return true;
00073 }
00074
00075 template <typename A, typename AI>
00076 bool
00077 is_proper(const Element<A, AI>& a)
00078 {
00079 return do_is_proper(a.structure(), a.series().monoid(), a);
00080 }
00081
00082
00083
00084 template <class A_, typename Auto, typename Weight>
00085 class EpsilonRemover;
00086
00087 template <class A_, typename Auto, typename Weight, int>
00088 struct test_for_non_positive_semiring
00089 {
00090 bool run(const Auto&) const
00091 {
00092 return true;
00093 }
00094 };
00095
00096 template <class A_, typename Auto, typename Weight>
00097 struct test_for_non_positive_semiring<A_, Auto, Weight, 0>
00098 {
00099 bool run(const Auto& a) const;
00100 };
00101
00102
00103
00104
00105
00106 template <class A_, typename Auto, typename Weight>
00107 class EpsilonRemover
00108 {
00109 AUTOMATON_TYPES(Auto);
00110 typedef typename series_set_elt_t::support_t support_t;
00111
00112 friend struct test_for_non_positive_semiring
00113 <A_, Auto, Weight, semiring_traits<semiring_t,
00114 semiring_elt_value_t>::is_positive>;
00115
00116
00117 automaton_t& a;
00118
00119 series_set_elt_t null_series;
00120 semiring_elt_t semiring_elt_zero,
00121 semiring_elt_unit;
00122 monoid_elt_t monoid_identity;
00123
00124
00125 public:
00126 EpsilonRemover(const AutomataBase<A_>&,
00127 Auto& aut)
00128 : a(aut),
00129 null_series(aut.series().zero_),
00130 semiring_elt_zero(aut.series().semiring().wzero_),
00131 semiring_elt_unit(aut.series().semiring().wone_),
00132 monoid_identity(aut.series().monoid().VCSN_EMPTY_)
00133 {}
00134
00135 void operator()(misc::direction_type dir)
00136 {
00137 test_for_non_positive_semiring
00138 <A_, Auto, Weight, semiring_traits<semiring_t,
00139 semiring_elt_value_t>::is_positive>
00140 nps;
00141 result_not_computable_if(!nps.run(a));
00142
00143 std::list<hstate_t> eps_states;
00144 if (dir == misc::backward)
00145 this->epsilon_covering(eps_states);
00146 else
00147 this->epsilon_co_covering(eps_states);
00148 result_not_computable_if(!spontaneous_suppression(eps_states));
00149 merge_transitions();
00150 }
00151
00152 private:
00153
00154
00155
00156
00157
00158
00159
00160 void epsilon_covering(std::list<hstate_t>& spontaneous_states)
00161 {
00162
00163 std::list<hstate_t> split_states;
00164 for_all_states(s, a)
00165 {
00166 bool eps_in = false;
00167 bool other_in = a.is_initial(*s);
00168
00169
00170
00171 std::list<htransition_t> transitions;
00172 for (rdelta_iterator e(a.value(), *s); ! e.done(); e.next())
00173 transitions.push_back(*e);
00174 for_all_(std::list<htransition_t>, e, transitions)
00175 {
00176 series_set_elt_t t = a.series_of(*e);
00177 semiring_elt_t eps_weight= t.get(monoid_identity);
00178 if (eps_weight == semiring_elt_zero)
00179 other_in = true ;
00180 else
00181 {
00182 eps_in=true;
00183 if (t.supp().size() > 1)
00184 other_in = true;
00185 }
00186 }
00187 if (eps_in)
00188 {
00189 if (other_in)
00190 split_states.push_back(*s);
00191 else
00192 spontaneous_states.push_back(*s);
00193 }
00194 }
00195
00196 for_all_(std::list<hstate_t>, s, split_states)
00197 {
00198 hstate_t eps_state = a.add_state();
00199 spontaneous_states.push_back(eps_state);
00200
00201 std::list<htransition_t> transitions;
00202 for (rdelta_iterator e(a.value(), *s); ! e.done(); e.next())
00203 transitions.push_back(*e);
00204 for_all_(std::list<htransition_t>, e, transitions)
00205 {
00206 series_set_elt_t t = a.series_of(*e);
00207 semiring_elt_t eps_weight= t.get(monoid_identity);
00208 if (eps_weight == semiring_elt_zero)
00209 continue;
00210 series_set_elt_t eps_label(a.structure().series());
00211 eps_label.assoc(monoid_identity.value(), eps_weight.value());
00212
00213 t.assoc(monoid_identity.value(), semiring_elt_zero.value());
00214 hstate_t source=a.src_of(*e);
00215 a.add_series_transition(source, eps_state, eps_label);
00216 if (t != null_series)
00217 a.add_series_transition(source, *s, t);
00218 a.del_transition(*e);
00219 }
00220
00221 if (a.is_final(*s))
00222 a.set_final(eps_state,a.get_final(*s));
00223 for (delta_iterator e(a.value(), *s); ! e.done(); e.next())
00224 a.add_series_transition(eps_state, a.dst_of(*e), a.series_of(*e));
00225
00226
00227
00228
00229
00230
00231
00232 }
00233 }
00234
00235
00236
00237
00238
00239 void initial_final_cleaner()
00240 {
00241 {
00242
00243 std::list<hstate_t> initial_states;
00244 for_all_initial_states(s, a)
00245 initial_states.push_back(*s);
00246 hstate_t new_initial=a.add_state();
00247 for_all_(std::list<hstate_t>, s, initial_states)
00248 {
00249 series_set_elt_t t = a.get_initial(*s);
00250 semiring_elt_t eps_weight= t.get(monoid_identity);
00251 t.assoc(monoid_identity, semiring_elt_zero.value());
00252 if (t != null_series)
00253 {
00254 a.unset_initial(*s);
00255 a.add_series_transition(new_initial, *s, t);
00256 if (eps_weight != semiring_elt_zero)
00257 {
00258 series_set_elt_t cst(a.structure().series());
00259 cst.assoc(monoid_identity, eps_weight.value());
00260 a.set_initial(*s, cst);
00261 }
00262 }
00263 }
00264 delta_iterator test(a.value(), new_initial);
00265 if (test.done())
00266 a.del_state(new_initial);
00267 else
00268 a.set_initial(new_initial);
00269 }
00270 {
00271
00272 std::list<hstate_t> final_states;
00273 for_all_final_states(s, a)
00274 final_states.push_back(*s);
00275 hstate_t new_final=a.add_state();
00276 for_all_(std::list<hstate_t>, s, final_states)
00277 {
00278 series_set_elt_t t = a.get_final(*s);
00279 semiring_elt_t eps_weight= t.get(monoid_identity);
00280 t.assoc(monoid_identity, semiring_elt_zero.value());
00281 if (t != null_series)
00282 {
00283 a.unset_final(*s);
00284 a.add_series_transition(*s, new_final, t);
00285 if(eps_weight != semiring_elt_zero)
00286 {
00287 series_set_elt_t cst(a.structure().series());
00288 cst.assoc(monoid_identity, eps_weight.value());
00289 a.set_final(*s, cst);
00290 }
00291 }
00292 }
00293 rdelta_iterator test(a.value(), new_final);
00294 if (test.done())
00295 a.del_state(new_final);
00296 else
00297 a.set_final(new_final);
00298 }
00299 }
00300
00301
00302
00303
00304
00305
00306
00307 void epsilon_co_covering(std::list<hstate_t>& spontaneous_states)
00308 {
00309
00310 std::list<hstate_t> split_states;
00311 for_all_states(s, a)
00312 {
00313 bool eps_out = false;
00314 bool other_out = a.is_final(*s);
00315
00316
00317
00318 std::list<htransition_t> transitions;
00319 for (delta_iterator e(a.value(), *s); !e.done(); e.next())
00320 transitions.push_back(*e);
00321 for_all_(std::list<htransition_t>, e, transitions)
00322 {
00323 series_set_elt_t t = a.series_of(*e);
00324 semiring_elt_t eps_weight= t.get(monoid_identity);
00325 if(eps_weight == semiring_elt_zero)
00326 other_out=true ;
00327 else
00328 {
00329 eps_out=true;
00330 if (t.supp().size() > 1)
00331 other_out=true;
00332 }
00333 }
00334 if (eps_out)
00335 {
00336 if (other_out)
00337 split_states.push_back(*s);
00338 else
00339 spontaneous_states.push_back(*s);
00340 }
00341 }
00342
00343 for_all_(std::list<hstate_t>, s, split_states)
00344 {
00345 hstate_t eps_state = a.add_state();
00346 spontaneous_states.push_back(eps_state);
00347
00348 std::list<htransition_t> transitions;
00349 for (delta_iterator e(a.value(), *s); !e.done(); e.next())
00350 transitions.push_back(*e);
00351 for_all_(std::list<htransition_t>, e, transitions)
00352 {
00353 series_set_elt_t t = a.series_of(*e);
00354 semiring_elt_t eps_weight= t.get(monoid_identity);
00355 if (eps_weight == semiring_elt_zero)
00356 continue;
00357 series_set_elt_t eps_label(a.structure().series());
00358 eps_label.assoc(monoid_identity.value(), eps_weight.value());
00359
00360 t.assoc(monoid_identity.value(), semiring_elt_zero.value());
00361 hstate_t target=a.dst_of(*e);
00362 a.add_series_transition(eps_state, target, eps_label);
00363 if (t != null_series)
00364 a.add_series_transition(*s, target, t);
00365 a.del_transition(*e);
00366 }
00367
00368 if (a.is_initial(*s))
00369 a.set_initial(eps_state,a.get_initial(*s));
00370 for (rdelta_iterator e(a.value(), *s); ! e.done(); e.next())
00371 a.add_series_transition(a.src_of(*e), eps_state, a.series_of(*e));
00372
00373
00374
00375
00376
00377
00378
00379 }
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 void positive_path_covering()
00391 {
00392 std::map<hstate_t,hstate_t> clones;
00393 std::list<hstate_t> states;
00394 for_all_states(s, a)
00395 states.push_back(*s);
00396 for_all_(std::list<hstate_t>, s, states)
00397 clones[*s]=a.add_state();
00398 hstate_t pos_final_state=a.add_state();
00399 hstate_t neg_final_state=a.add_state();
00400 std::list<htransition_t> transitions;
00401 for_all_transitions(e, a)
00402 transitions.push_back(*e);
00403 for_all_(std::list<htransition_t>, e, transitions)
00404 {
00405 series_set_elt_t posit = a.series_of(*e);
00406 series_set_elt_t negat(a.structure().series());
00407 support_t su = posit.supp();
00408 for_all_(support_t, x, su)
00409 {
00410 semiring_elt_t weight=posit.get(*x);
00411 if (weight < semiring_elt_zero)
00412 {
00413 negat.assoc(*x,-weight.value());
00414 posit.assoc(*x,semiring_elt_zero.value());
00415 }
00416 }
00417 hstate_t src=a.src_of(*e), dst=a.dst_of(*e);
00418 if (posit != null_series)
00419 a.add_series_transition(clones[src], clones[dst], posit);
00420 if (negat != null_series)
00421 {
00422 a.add_series_transition(src, clones[dst], negat);
00423 a.add_series_transition(clones[src], dst, negat);
00424 if (posit != null_series)
00425 a.add_series_transition(src, dst, posit);
00426 a.del_transition(*e);
00427 }
00428 }
00429 states.clear();
00430 for_all_initial_states(s, a)
00431 states.push_back(*s);
00432 for_all_(std::list<hstate_t>, s, states)
00433 {
00434 series_set_elt_t posit = a.get_initial(*s);
00435 series_set_elt_t negat(a.structure().series());
00436 support_t su = posit.supp();
00437 for_all_(support_t, x, su)
00438 {
00439 semiring_elt_t weight = posit.get(*x);
00440 if (weight < semiring_elt_zero)
00441 {
00442 negat.assoc(*x,-weight.value());
00443 posit.assoc(*x,semiring_elt_zero.value());
00444 }
00445 }
00446 if (negat != null_series)
00447 {
00448 a.set_initial(clones[*s], negat);
00449 a.unset_initial(*s);
00450 if (posit != null_series)
00451 a.set_initial(*s,posit);
00452 }
00453 }
00454 states.clear();
00455 for_all_final_states(s, a)
00456 states.push_back(*s);
00457 for_all_(std::list<hstate_t>, s, states)
00458 {
00459 series_set_elt_t posit = a.get_final(*s);
00460 series_set_elt_t negat(a.structure().series());
00461 support_t su = posit.supp();
00462 for_all_(support_t, x, su)
00463 {
00464 semiring_elt_t weight=posit.get(*x);
00465 if (weight < semiring_elt_zero)
00466 {
00467 negat.assoc(*x,-weight.value());
00468 posit.assoc(*x,semiring_elt_zero.value());
00469 }
00470 }
00471 if (negat != null_series)
00472 {
00473 a.add_series_transition(*s, neg_final_state, negat);
00474 a.add_series_transition(clones[*s], pos_final_state, negat);
00475 }
00476 a.unset_final(*s);
00477 if (posit != null_series)
00478 {
00479 a.add_series_transition(*s, pos_final_state, posit);
00480 a.add_series_transition(clones[*s], neg_final_state, posit);
00481 }
00482 }
00483 a.set_final(pos_final_state);
00484 series_set_elt_t mss = a.get_final(pos_final_state);
00485 mss.assoc(monoid_identity,-semiring_elt_unit.value());
00486 a.set_final(neg_final_state,mss);
00487 accessible_here(a);
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497 bool spontaneous_suppression(std::list<hstate_t>& sp_states)
00498 {
00499 for_all_(std::list<hstate_t>, s, sp_states)
00500 {
00501 std::list<htransition_t> incoming_transitions;
00502
00503 for (rdelta_iterator e(a.value(), *s); ! e.done(); e.next())
00504 {
00505 if (a.src_of(*e) == a.dst_of(*e))
00506 incoming_transitions.push_front(*e);
00507 else
00508 incoming_transitions.push_back(*e);
00509 }
00510 bool hasloop=false;
00511 series_set_elt_t loop_series(a.structure().series());
00512
00513 while (!incoming_transitions.empty())
00514 {
00515 htransition_t& loop=incoming_transitions.front();
00516 if(a.src_of(loop)==a.dst_of(loop))
00517 {
00518 hasloop=true;
00519 loop_series += a.series_of(loop);
00520 incoming_transitions.pop_front();
00521 }
00522 else
00523 break;
00524 }
00525 if (hasloop)
00526 {
00527 if (!loop_series.get(monoid_identity).starable())
00528 return false;
00529 loop_series = loop_series.star();
00530 }
00531 std::list<htransition_t> outgoing_transitions;
00532 for (delta_iterator e(a.value(), *s); ! e.done(); e.next())
00533 if (a.src_of(*e)!=a.dst_of(*e))
00534 outgoing_transitions.push_back(*e);
00535 for_all_(std::list<htransition_t>, e, incoming_transitions)
00536 for_all_(std::list<htransition_t>, f, outgoing_transitions)
00537 if (hasloop)
00538 a.add_series_transition(a.src_of(*e), a.dst_of(*f),
00539 a.series_of(*e)*loop_series*a.series_of(*f));
00540 else
00541 a.add_series_transition(a.src_of(*e), a.dst_of(*f),
00542 a.series_of(*e)*a.series_of(*f));
00543 if (a.is_final(*s))
00544 {
00545 series_set_elt_t final_s = a.get_final(*s);
00546 for_all_(std::list<htransition_t>, e, incoming_transitions)
00547 {
00548 hstate_t p = a.src_of(*e);
00549 series_set_elt_t t = a.get_final(p);
00550 if (hasloop)
00551 t += a.series_of(*e)*loop_series*final_s;
00552 else
00553 t += a.series_of(*e)*final_s;
00554 a.unset_final(p);
00555 if (t != null_series)
00556 a.set_final(p,t);
00557 }
00558 }
00559 if (a.is_initial(*s))
00560 {
00561 series_set_elt_t initial_s=a.get_initial(*s);
00562 for_all_(std::list<htransition_t>, f, outgoing_transitions)
00563 {
00564 hstate_t p = a.dst_of(*f);
00565 series_set_elt_t t = a.get_initial(p);
00566 if (hasloop)
00567 t += initial_s*loop_series*a.series_of(*f);
00568 else
00569 t += initial_s*a.series_of(*f);
00570 a.unset_initial(p);
00571 if (t != null_series)
00572 a.set_initial(p,t);
00573 }
00574 }
00575 a.del_state(*s);
00576 }
00577 return true;
00578 }
00579
00580
00581 void merge_transitions()
00582 {
00583 typedef std::map<hstate_t, series_set_elt_t> map_t;
00584 for_all_states(s, a)
00585 {
00586 map_t map;
00587 std::list<htransition_t> transitions;
00588 for (delta_iterator e(a.value(), *s); ! e.done(); e.next())
00589 {
00590 hstate_t target = a.dst_of(*e);
00591 transitions.push_back(*e);
00592 typename map_t::iterator it = map.find(target);
00593 if (it == map.end())
00594 map.insert(std::pair<hstate_t, series_set_elt_t>(target,
00595 a.series_of(*e)));
00596 else
00597 it->second += a.series_of(*e);
00598 }
00599 for_all_(std::list<htransition_t>, e, transitions)
00600 a.del_transition(*e);
00601 for_all_(map_t, it, map)
00602 a.add_series_transition(*s, it->first, it->second);
00603 }
00604 }
00605
00606 };
00607
00608
00609 template <class A_, typename Auto, typename Weight>
00610 bool test_for_non_positive_semiring<A_, Auto, Weight, 0>::run(const Auto& a) const
00611 {
00612 AUTOMATON_TYPES(Auto);
00613
00614 std::list<hstate_t> eps_states;
00615 automaton_t test(a);
00616 EpsilonRemover<A_, Auto, Weight> epsTest(test.structure(), test);
00617 epsTest.positive_path_covering();
00618 epsTest.epsilon_covering(eps_states);
00619 return epsTest.spontaneous_suppression(eps_states);
00620 }
00621
00622
00623
00624
00625
00626
00627
00628
00629 template<class A_, typename Auto, typename Weight>
00630 void
00631 do_eps_removal_here(const AutomataBase<A_>& a_set,
00632 const Weight&,
00633 Auto& a,
00634 misc::direction_type dir)
00635 {
00636 BENCH_TASK_SCOPED("eps_removal");
00637 AUTOMATON_TYPES(Auto);
00638 EpsilonRemover<A_, Auto, Weight> algo(a_set, a);
00639 algo(dir);
00640 }
00641
00642 template<typename A, typename AI>
00643 void
00644 eps_removal_here(Element<A, AI>& a, misc::direction_type dir)
00645 {
00646 typedef Element<A, AI> automaton_t;
00647 AUTOMATON_TYPES(automaton_t);
00648
00649 do_eps_removal_here(a.structure(),
00650 SELECT(semiring_elt_value_t),
00651 a, dir);
00652 }
00653
00654 template<typename A, typename AI>
00655 Element<A, AI>
00656 eps_removal(const Element<A, AI>& a, misc::direction_type dir)
00657 {
00658 typedef Element<A, AI> automaton_t;
00659 AUTOMATON_TYPES(automaton_t);
00660
00661 automaton_t ret(a);
00662 do_eps_removal_here(ret.structure(),
00663 SELECT(semiring_elt_value_t),
00664 ret, dir);
00665 return ret;
00666 }
00667
00668 template<typename A, typename AI>
00669 void
00670 backward_eps_removal_here(Element<A, AI>& a)
00671 {
00672 typedef Element<A, AI> automaton_t;
00673 AUTOMATON_TYPES(automaton_t);
00674
00675 do_eps_removal_here(a.structure(),
00676 SELECT(semiring_elt_value_t),
00677 a, misc::backward);
00678 }
00679
00680 template<typename A, typename AI>
00681 Element<A, AI>
00682 backward_eps_removal(const Element<A, AI>& a)
00683 {
00684 typedef Element<A, AI> automaton_t;
00685 AUTOMATON_TYPES(automaton_t);
00686
00687 automaton_t ret(a);
00688 do_eps_removal_here(ret.structure(),
00689 SELECT(semiring_elt_value_t),
00690 ret, misc::backward);
00691 return ret;
00692 }
00693
00694 template<typename A, typename AI>
00695 void
00696 forward_eps_removal_here(Element<A, AI>& a)
00697 {
00698 typedef Element<A, AI> automaton_t;
00699 AUTOMATON_TYPES(automaton_t);
00700
00701 do_eps_removal_here(a.structure(),
00702 SELECT(semiring_elt_value_t),
00703 a, misc::forward);
00704 }
00705
00706 template<typename A, typename AI>
00707 Element<A, AI>
00708 forward_eps_removal(const Element<A, AI>& a)
00709 {
00710 typedef Element<A, AI> automaton_t;
00711 AUTOMATON_TYPES(automaton_t);
00712
00713 automaton_t ret(a);
00714 do_eps_removal_here(ret.structure(),
00715 SELECT(semiring_elt_value_t),
00716 ret, misc::forward);
00717 return ret;
00718 }
00719
00720 }
00721
00722 #endif // ! VCSN_ALGORITHMS_EPS_REMOVAL_HXX