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     precondition(is_realtime(work));
00043     TIMER_SCOPED("complete");
00044     typedef Element<A, AI> automaton_t;
00045     AUTOMATON_TYPES(automaton_t);
00046     AUTOMATON_FREEMONOID_TYPES(automaton_t);
00047     hstate_t sink_state;
00048     bool sink_added = false;
00049     std::list<hstate_t> dst;
00050 
00051     for_all_const_states(s, work)
00052       for_all_const_letters(l, work.structure().series().monoid().alphabet())
00053       {
00054         dst.clear();
00055         work.letter_deltac(dst, *s, *l, delta_kind::states());
00056         if (dst.size() == 0)
00057         {
00058           if (not sink_added)
00059           {
00060             sink_state = work.add_state();
00061             sink_added = true;
00062           }
00063           work.add_letter_transition(*s, sink_state, *l);
00064         }
00065       }
00066 
00067     if (work.states().size() ==  0)
00068     {
00069       sink_state = work.add_state();
00070       sink_added = true;
00071       work.set_initial(sink_state);
00072     }
00073 
00074     if (sink_added)
00075       for_all_const_letters(l, work.structure().series().monoid().alphabet())
00076         work.add_letter_transition(sink_state, sink_state, *l);
00077   }
00078 
00079   
00080 
00081 
00082 
00083   template <typename A, typename AI>
00084   Element<A, AI>
00085   complete(const Element<A, AI>& e)
00086   {
00087     Element<A, AI> res(e);
00088     complete_here(res);
00089     return res;
00090   }
00091 
00092   
00093 
00094 
00095 
00096   template <typename A, typename AI>
00097   bool
00098   is_complete(const Element<A, AI>& e)
00099   {
00100     precondition(is_realtime(e));
00101     TIMER_SCOPED("is_complete");
00102     if (e.states().size() ==  0)
00103       return false;
00104     typedef Element<A, AI> automaton_t;
00105     AUTOMATON_TYPES(automaton_t);
00106     AUTOMATON_FREEMONOID_TYPES(automaton_t);
00107     const alphabet_t& alpha = e.structure().series().monoid().alphabet();
00108     for_all_const_states(i, e)
00109     {
00110       std::set<hstate_t> dst;
00111       for_all_const_letters(j, alpha)
00112       {
00113         dst.clear();
00114         e.letter_deltac(dst, *i, *j, delta_kind::states());
00115 
00116         if (dst.size() == 0)
00117           return false;
00118       }
00119     }
00120     return true;
00121   }
00122 
00123 } 
00124 
00125 #endif // ! VCSN_ALGORITHMS_COMPLETE_HXX