00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_COMPLETE_HXX
00018 # define VCSN_ALGORITHMS_COMPLETE_HXX
00019
00020 # include <vaucanson/algorithms/complete.hh>
00021
00022 # ifndef VCSN_NDEBUG
00023 # include <vaucanson/algorithms/realtime.hh>
00024 # endif // ! VCSN_NDEBUG
00025
00026 # include <vaucanson/automata/concept/automata_base.hh>
00027 # include <vaucanson/misc/usual_macros.hh>
00028
00029 # include <list>
00030 # include <set>
00031
00032 namespace vcsn {
00033
00034
00035
00036
00037
00038 template <typename A, typename AI>
00039 void
00040 complete_here(Element<A, AI>& work)
00041 {
00042
00043
00044 precondition(is_realtime(work));
00045 BENCH_TASK_SCOPED("complete");
00046 typedef Element<A, AI> automaton_t;
00047 AUTOMATON_TYPES(automaton_t);
00048 AUTOMATON_FREEMONOID_TYPES(automaton_t);
00049
00050 hstate_t sink_state = work.add_state();
00051 bool sink_needed = false;
00052
00053
00054
00055
00056
00057
00058 if (work.states().size() == 1)
00059 {
00060 sink_needed = true;
00061 work.set_initial(sink_state);
00062 }
00063
00064 for_all_const_states(s, work)
00065 for_all_const_letters(l, work.structure().series().monoid().alphabet())
00066 {
00067 bool empty = true;
00068 for (delta_iterator t(work.value(), *s); ! t.done(); t.next())
00069 {
00070 monoid_elt_t w(work.series_of(*t).structure().monoid(), *l);
00071 if (work.series_of(*t).get(w) != work.series().semiring().wzero_)
00072 {
00073 empty = false;
00074 break;
00075 }
00076 }
00077 if (empty)
00078 {
00079 sink_needed = true;
00080 work.add_letter_transition(*s, sink_state, *l);
00081 }
00082 }
00083
00084 if (!sink_needed)
00085 work.del_state(sink_state);
00086 }
00087
00088
00089
00090
00091
00092 template <typename A, typename AI>
00093 Element<A, AI>
00094 complete(const Element<A, AI>& e)
00095 {
00096 Element<A, AI> res(e);
00097 complete_here(res);
00098 return res;
00099 }
00100
00101
00102
00103
00104
00105 template <typename A, typename AI>
00106 bool
00107 is_complete(const Element<A, AI>& e)
00108 {
00109 precondition(is_realtime(e));
00110 BENCH_TASK_SCOPED("is_complete");
00111 if (e.states().size() == 0)
00112 return false;
00113 typedef Element<A, AI> automaton_t;
00114 AUTOMATON_TYPES(automaton_t);
00115 AUTOMATON_FREEMONOID_TYPES(automaton_t);
00116 const alphabet_t& alpha = e.structure().series().monoid().alphabet();
00117 for_all_const_states(i, e)
00118 {
00119 for_all_const_letters(j, alpha)
00120 {
00121 bool empty = true;
00122 for (delta_iterator t(e.value(), *i);
00123 ! t.done() && empty;
00124 t.next())
00125 {
00126 monoid_elt_t w(e.series_of(*t).structure().monoid(), *j);
00127 if (e.series_of(*t).get(w) != e.series().semiring().wzero_)
00128 {
00129 empty = false;
00130 break;
00131 }
00132 }
00133
00134 if (empty)
00135 return false;
00136 }
00137 }
00138 return true;
00139 }
00140
00141 }
00142
00143 #endif // ! VCSN_ALGORITHMS_COMPLETE_HXX