17 #ifndef VCSN_ALGORITHMS_EPS_REMOVAL_HXX
18 # define VCSN_ALGORITHMS_EPS_REMOVAL_HXX
22 # include <vaucanson/automata/concept/automata_base.hh>
23 # include <vaucanson/algebra/concept/freemonoid_product.hh>
24 # include <vaucanson/misc/usual_macros.hh>
33 template <
class A,
typename M,
typename AI>
35 do_is_proper(
const AutomataBase<A>&,
const M&,
const Element<A, AI>& a)
37 BENCH_TASK_SCOPED(
"is_proper (automaton)");
38 typedef Element<A, AI> automaton_t;
39 AUTOMATON_TYPES(automaton_t);
41 for_all_const_transitions(e, a)
46 series_set_elt_t label = a.series_of(*e);
47 for_all_const_(series_set_elt_t::support_t, it, label.supp())
55 template <
class A,
typename F,
typename S,
typename AI>
57 do_is_proper(
const AutomataBase<A>&,
58 const algebra::FreeMonoidProduct<F, S>&,
59 const Element<A, AI>& a)
61 BENCH_TASK_SCOPED(
"is_proper (FMP)");
62 typedef Element<A, AI> automaton_t;
63 AUTOMATON_TYPES(automaton_t);
65 for_all_const_transitions(e, a)
67 series_set_elt_t label = a.series_of(*e);
68 for_all_const_(series_set_elt_t::support_t, it, label.supp())
69 if ((*it).first.empty() && (*it).second.empty())
75 template <
typename A,
typename AI>
79 return do_is_proper(a.
structure(), a.series().monoid(), a);
84 template <
class A_,
typename Auto,
typename Weight>
87 template <
class A_,
typename Auto,
typename Weight,
int>
88 struct test_for_non_positive_semiring
90 bool run(
const Auto&)
const
96 template <
class A_,
typename Auto,
typename Weight>
97 struct test_for_non_positive_semiring<A_, Auto, Weight, 0>
99 bool run(
const Auto& a)
const;
106 template <
class A_,
typename Auto,
typename Weight>
109 AUTOMATON_TYPES(Auto);
110 typedef typename series_set_elt_t::support_t support_t;
112 friend struct test_for_non_positive_semiring
113 <A_, Auto, Weight, semiring_traits<semiring_t,
114 semiring_elt_value_t>::is_positive>;
119 series_set_elt_t null_series;
120 semiring_elt_t semiring_elt_zero,
122 monoid_elt_t monoid_identity;
126 EpsilonRemover(const AutomataBase<A_>&,
129 null_series(aut.series().zero_),
130 semiring_elt_zero(aut.series().semiring().wzero_),
131 semiring_elt_unit(aut.series().semiring().wone_),
132 monoid_identity(aut.series().monoid().VCSN_EMPTY_)
137 test_for_non_positive_semiring
138 <A_, Auto, Weight, semiring_traits<semiring_t,
139 semiring_elt_value_t>::is_positive>
141 result_not_computable_if(!nps.run(a));
142 std::list<hstate_t> eps_states;
143 if (dir == misc::backward)
144 this->epsilon_covering(eps_states);
146 this->epsilon_co_covering(eps_states);
147 result_not_computable_if(!spontaneous_suppression(eps_states));
159 void epsilon_covering(std::list<hstate_t>& spontaneous_states)
162 std::list<hstate_t> split_states;
166 bool other_in = a.is_initial(*s);
171 for (rdelta_iterator e(a.value(), *s); ! e.done(); e.next())
172 transitions.push_back(*e);
173 for_all_(std::list<htransition_t>, e, transitions)
175 series_set_elt_t t = a.series_of(*e);
176 semiring_elt_t eps_weight= t.get(monoid_identity);
177 if (eps_weight == semiring_elt_zero)
182 if (t.supp().size() > 1)
189 split_states.push_back(*s);
191 spontaneous_states.push_back(*s);
195 for_all_(std::list<hstate_t>, s, split_states)
197 hstate_t eps_state = a.add_state();
198 spontaneous_states.push_back(eps_state);
200 std::list<htransition_t> transitions;
201 for (rdelta_iterator e(a.value(), *s); ! e.done(); e.next())
202 transitions.push_back(*e);
203 for_all_(std::list<htransition_t>, e, transitions)
205 series_set_elt_t t = a.series_of(*e);
206 semiring_elt_t eps_weight= t.get(monoid_identity);
207 if (eps_weight == semiring_elt_zero)
209 series_set_elt_t eps_label(a.structure().series());
210 eps_label.assoc(monoid_identity.value(), eps_weight.value());
212 t.assoc(monoid_identity.value(), semiring_elt_zero.value());
213 hstate_t source=a.src_of(*e);
214 a.add_series_transition(source, eps_state, eps_label);
215 if (t != null_series)
216 a.add_series_transition(source, *s, t);
217 a.del_transition(*e);
221 a.set_final(eps_state,a.get_final(*s));
222 for (delta_iterator e(a.value(), *s); ! e.done(); e.next())
223 a.add_series_transition(eps_state, a.dst_of(*e), a.series_of(*e));
238 void initial_final_cleaner()
242 std::list<hstate_t> initial_states;
243 for_all_initial_states(s, a)
244 initial_states.push_back(*s);
245 hstate_t new_initial=a.add_state();
246 for_all_(std::list<hstate_t>, s, initial_states)
248 series_set_elt_t t = a.get_initial(*s);
249 semiring_elt_t eps_weight= t.get(monoid_identity);
250 t.assoc(monoid_identity, semiring_elt_zero.value());
251 if (t != null_series)
254 a.add_series_transition(new_initial, *s, t);
255 if (eps_weight != semiring_elt_zero)
257 series_set_elt_t cst(a.structure().series());
258 cst.assoc(monoid_identity, eps_weight.value());
259 a.set_initial(*s, cst);
263 delta_iterator test(a.value(), new_initial);
265 a.del_state(new_initial);
267 a.set_initial(new_initial);
271 std::list<hstate_t> final_states;
272 for_all_final_states(s, a)
273 final_states.push_back(*s);
274 hstate_t new_final=a.add_state();
275 for_all_(std::list<hstate_t>, s, final_states)
277 series_set_elt_t t = a.get_final(*s);
278 semiring_elt_t eps_weight= t.get(monoid_identity);
279 t.assoc(monoid_identity, semiring_elt_zero.value());
280 if (t != null_series)
283 a.add_series_transition(*s, new_final, t);
284 if(eps_weight != semiring_elt_zero)
286 series_set_elt_t cst(a.structure().series());
287 cst.assoc(monoid_identity, eps_weight.value());
288 a.set_final(*s, cst);
292 rdelta_iterator test(a.value(), new_final);
294 a.del_state(new_final);
296 a.set_final(new_final);
306 void epsilon_co_covering(std::list<hstate_t>& spontaneous_states)
309 std::list<hstate_t> split_states;
312 bool eps_out =
false;
313 bool other_out = a.is_final(*s);
317 std::list<htransition_t> transitions;
318 for (delta_iterator e(a.value(), *s); !e.done(); e.next())
319 transitions.push_back(*e);
320 for_all_(std::list<htransition_t>, e, transitions)
322 series_set_elt_t t = a.series_of(*e);
323 semiring_elt_t eps_weight= t.get(monoid_identity);
324 if(eps_weight == semiring_elt_zero)
329 if (t.supp().size() > 1)
336 split_states.push_back(*s);
338 spontaneous_states.push_back(*s);
342 for_all_(std::list<hstate_t>, s, split_states)
344 hstate_t eps_state = a.add_state();
345 spontaneous_states.push_back(eps_state);
347 std::list<htransition_t> transitions;
348 for (delta_iterator e(a.value(), *s); !e.done(); e.next())
349 transitions.push_back(*e);
350 for_all_(std::list<htransition_t>, e, transitions)
352 series_set_elt_t t = a.series_of(*e);
353 semiring_elt_t eps_weight= t.get(monoid_identity);
354 if (eps_weight == semiring_elt_zero)
356 series_set_elt_t eps_label(a.structure().series());
357 eps_label.assoc(monoid_identity.value(), eps_weight.value());
359 t.assoc(monoid_identity.value(), semiring_elt_zero.value());
360 hstate_t target=a.dst_of(*e);
361 a.add_series_transition(eps_state, target, eps_label);
362 if (t != null_series)
363 a.add_series_transition(*s, target, t);
364 a.del_transition(*e);
367 if (a.is_initial(*s))
368 a.set_initial(eps_state,a.get_initial(*s));
369 for (rdelta_iterator e(a.value(), *s); ! e.done(); e.next())
370 a.add_series_transition(a.src_of(*e), eps_state, a.series_of(*e));
389 void positive_path_covering()
391 std::map<hstate_t,hstate_t> clones;
392 std::list<hstate_t> states;
394 states.push_back(*s);
395 for_all_(std::list<hstate_t>, s, states)
396 clones[*s]=a.add_state();
397 hstate_t pos_final_state=a.add_state();
398 hstate_t neg_final_state=a.add_state();
399 std::list<htransition_t> transitions;
400 for_all_transitions(e, a)
401 transitions.push_back(*e);
402 for_all_(std::list<htransition_t>, e, transitions)
404 series_set_elt_t posit = a.series_of(*e);
405 series_set_elt_t negat(a.structure().series());
406 support_t su = posit.supp();
407 for_all_(support_t, x, su)
409 semiring_elt_t weight=posit.get(*x);
410 if (weight < semiring_elt_zero)
412 negat.assoc(*x,-weight.value());
413 posit.assoc(*x,semiring_elt_zero.value());
416 hstate_t src=a.src_of(*e), dst=a.dst_of(*e);
417 if (posit != null_series)
418 a.add_series_transition(clones[src], clones[dst], posit);
419 if (negat != null_series)
421 a.add_series_transition(src, clones[dst], negat);
422 a.add_series_transition(clones[src], dst, negat);
423 if (posit != null_series)
424 a.add_series_transition(src, dst, posit);
425 a.del_transition(*e);
429 for_all_initial_states(s, a)
430 states.push_back(*s);
431 for_all_(std::list<hstate_t>, s, states)
433 series_set_elt_t posit = a.get_initial(*s);
434 series_set_elt_t negat(a.structure().series());
435 support_t su = posit.supp();
436 for_all_(support_t, x, su)
438 semiring_elt_t weight = posit.get(*x);
439 if (weight < semiring_elt_zero)
441 negat.assoc(*x,-weight.value());
442 posit.assoc(*x,semiring_elt_zero.value());
445 if (negat != null_series)
447 a.set_initial(clones[*s], negat);
449 if (posit != null_series)
450 a.set_initial(*s,posit);
454 for_all_final_states(s, a)
455 states.push_back(*s);
456 for_all_(std::list<hstate_t>, s, states)
458 series_set_elt_t posit = a.get_final(*s);
459 series_set_elt_t negat(a.structure().series());
460 support_t su = posit.supp();
461 for_all_(support_t, x, su)
463 semiring_elt_t weight=posit.get(*x);
464 if (weight < semiring_elt_zero)
466 negat.assoc(*x,-weight.value());
467 posit.assoc(*x,semiring_elt_zero.value());
470 if (negat != null_series)
472 a.add_series_transition(*s, neg_final_state, negat);
473 a.add_series_transition(clones[*s], pos_final_state, negat);
476 if (posit != null_series)
478 a.add_series_transition(*s, pos_final_state, posit);
479 a.add_series_transition(clones[*s], neg_final_state, posit);
482 a.set_final(pos_final_state);
483 series_set_elt_t mss = a.get_final(pos_final_state);
484 mss.assoc(monoid_identity,-semiring_elt_unit.value());
485 a.set_final(neg_final_state,mss);
491 void absolute_weight()
493 std::list<htransition_t> transitions;
494 for_all_transitions(e, a)
495 transitions.push_back(*e);
496 for_all_(std::list<htransition_t>, e, transitions)
498 series_set_elt_t label = a.series_of(*e);
499 support_t support = label.supp();
500 for_all_(support_t, x, support)
502 semiring_elt_t weight=label.get(*x);
503 if (weight < semiring_elt_zero)
504 label.assoc(*x,-weight.value());
506 hstate_t src=a.src_of(*e), dst=a.dst_of(*e);
507 a.del_transition(*e);
508 a.add_series_transition(src, dst, label);
510 std::list<hstate_t> states;
511 for_all_initial_states(s, a)
512 states.push_back(*s);
513 for_all_(std::list<hstate_t>, s, states)
515 series_set_elt_t label = a.get_initial(*s);
516 support_t support = label.supp();
517 for_all_(support_t, x, support)
519 semiring_elt_t weight = label.get(*x);
520 if (weight < semiring_elt_zero)
521 label.assoc(*x,-weight.value());
523 a.set_initial(*s,label);
526 for_all_final_states(s, a)
527 states.push_back(*s);
528 for_all_(std::list<hstate_t>, s, states)
530 series_set_elt_t label = a.get_final(*s);
531 support_t support = label.supp();
532 for_all_(support_t, x, support)
534 semiring_elt_t weight = label.get(*x);
535 if (weight < semiring_elt_zero)
536 label.assoc(*x,-weight.value());
538 a.set_final(*s,label);
549 bool spontaneous_suppression(std::list<hstate_t>& sp_states)
551 for_all_(std::list<hstate_t>, s, sp_states)
553 std::list<htransition_t> incoming_transitions;
555 for (rdelta_iterator e(a.value(), *s); ! e.done(); e.next())
557 if (a.src_of(*e) == a.dst_of(*e))
558 incoming_transitions.push_front(*e);
560 incoming_transitions.push_back(*e);
563 series_set_elt_t loop_series(a.structure().series());
565 while (!incoming_transitions.empty())
567 htransition_t& loop=incoming_transitions.front();
568 if(a.src_of(loop)==a.dst_of(loop))
571 loop_series += a.series_of(loop);
572 incoming_transitions.pop_front();
579 if (!loop_series.get(monoid_identity).starable())
581 loop_series = loop_series.star();
583 std::list<htransition_t> outgoing_transitions;
584 for (delta_iterator e(a.value(), *s); ! e.done(); e.next())
585 if (a.src_of(*e)!=a.dst_of(*e))
586 outgoing_transitions.push_back(*e);
587 for_all_(std::list<htransition_t>, e, incoming_transitions)
588 for_all_(std::list<htransition_t>, f, outgoing_transitions)
590 a.add_series_transition(a.src_of(*e), a.dst_of(*f),
591 a.series_of(*e)*loop_series*a.series_of(*f));
593 a.add_series_transition(a.src_of(*e), a.dst_of(*f),
594 a.series_of(*e)*a.series_of(*f));
597 series_set_elt_t final_s = a.get_final(*s);
598 for_all_(std::list<htransition_t>, e, incoming_transitions)
600 hstate_t p = a.src_of(*e);
601 series_set_elt_t t = a.get_final(p);
603 t += a.series_of(*e)*loop_series*final_s;
605 t += a.series_of(*e)*final_s;
607 if (t != null_series)
611 if (a.is_initial(*s))
613 series_set_elt_t initial_s=a.get_initial(*s);
614 for_all_(std::list<htransition_t>, f, outgoing_transitions)
616 hstate_t p = a.dst_of(*f);
617 series_set_elt_t t = a.get_initial(p);
619 t += initial_s*loop_series*a.series_of(*f);
621 t += initial_s*a.series_of(*f);
623 if (t != null_series)
633 void merge_transitions()
635 typedef std::map<hstate_t, series_set_elt_t> map_t;
639 std::list<htransition_t> transitions;
640 for (delta_iterator e(a.value(), *s); ! e.done(); e.next())
642 hstate_t target = a.dst_of(*e);
643 transitions.push_back(*e);
644 typename map_t::iterator it = map.find(target);
646 map.insert(std::pair<hstate_t, series_set_elt_t>(target,
649 it->second += a.series_of(*e);
651 for_all_(std::list<htransition_t>, e, transitions)
652 a.del_transition(*e);
653 for_all_(map_t, it, map)
654 if(it->second != null_series)
655 a.add_series_transition(*s, it->first, it->second);
662 template <class A_, typename Auto, typename Weight>
663 bool test_for_non_positive_semiring<A_, Auto, Weight, 0>::run(const Auto& a)
const
665 AUTOMATON_TYPES(Auto);
667 std::list<hstate_t> eps_states;
669 EpsilonRemover<A_, Auto, Weight> epsTest(test.structure(), test);
670 epsTest.absolute_weight();
671 epsTest.epsilon_covering(eps_states);
672 return epsTest.spontaneous_suppression(eps_states);
682 template<
class A_,
typename Auto,
typename Weight>
684 do_eps_removal_here(
const AutomataBase<A_>& a_set,
689 BENCH_TASK_SCOPED(
"eps_removal");
690 AUTOMATON_TYPES(Auto);
691 EpsilonRemover<A_, Auto, Weight> algo(a_set, a);
695 template<
typename A,
typename AI>
700 AUTOMATON_TYPES(automaton_t);
703 SELECT(semiring_elt_value_t),
707 template<
typename A,
typename AI>
712 AUTOMATON_TYPES(automaton_t);
715 do_eps_removal_here(ret.structure(),
716 SELECT(semiring_elt_value_t),
721 template<
typename A,
typename AI>
726 AUTOMATON_TYPES(automaton_t);
729 SELECT(semiring_elt_value_t),
733 template<
typename A,
typename AI>
738 AUTOMATON_TYPES(automaton_t);
741 do_eps_removal_here(ret.structure(),
742 SELECT(semiring_elt_value_t),
743 ret, misc::backward);
747 template<
typename A,
typename AI>
752 AUTOMATON_TYPES(automaton_t);
755 SELECT(semiring_elt_value_t),
759 template<
typename A,
typename AI>
764 AUTOMATON_TYPES(automaton_t);
767 do_eps_removal_here(ret.structure(),
768 SELECT(semiring_elt_value_t),
775 #endif // ! VCSN_ALGORITHMS_EPS_REMOVAL_HXX