00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 #ifndef VCSN_ALGORITHMS_REALTIME_HXX
00018 # define VCSN_ALGORITHMS_REALTIME_HXX
00019 
00020 # include <vaucanson/algorithms/realtime.hh>
00021 
00022 # include <vaucanson/algorithms/eps_removal.hh>
00023 # include <vaucanson/algorithms/accessible.hh>
00024 # include <vaucanson/algorithms/cut_up.hh>
00025 
00026 # include <vaucanson/automata/concept/automata_base.hh>
00027 
00028 # include <deque>
00029 # include <set>
00030 
00031 namespace vcsn {
00032 
00033 
00034   
00035 
00036 
00037 
00038   template <class Auto, class Label>
00039   int do_realtime_words(Auto& a,
00040                         typename Auto::hstate_t start,
00041                         typename Auto::hstate_t stop,
00042                         const Label& label, bool initial, bool final)
00043   {
00044     AUTOMATON_TYPES(Auto);
00045     hstate_t                    s1;
00046     semiring_elt_t              s_ident = algebra::identity_as<semiring_elt_value_t>
00047       ::of(a.structure().series().semiring());
00048 
00049 
00050     if (label.supp().begin() == label.supp().end())
00051       return 0;
00052 
00053     monoid_elt_t m1(a.structure().series().monoid(), *label.supp().begin());
00054     monoid_elt_value_t w1 = m1.value();
00055 
00056     unsigned int size = m1.length();
00057 
00058     if (size > 1)
00059     {
00060       monoid_elt_t m(a.structure().series().monoid());
00061 
00062       semiring_elt_t s = label.get(m1);
00063       series_set_elt_t in_series(a.structure().series());
00064       typename monoid_elt_t::iterator l = m1.begin();
00065 
00066       m = *l;
00067 
00068       in_series.assoc(m, s);
00069 
00070       if (initial)
00071       {
00072         hstate_t s0 = a.add_state();
00073         a.set_initial(s0, in_series);
00074         a.unset_initial(stop);
00075         s1 = s0;
00076       }
00077       else
00078       {
00079         hstate_t s0 = start;
00080         s1 = a.add_state();
00081         a.add_series_transition(s0, s1, in_series);
00082       }
00083 
00084       l++;
00085       for (typename monoid_elt_t::iterator end = m1.begin() + (size - 1);
00086            l != end; ++l)
00087       {
00088         m = *l;
00089         hstate_t s0 = s1;
00090         s1 = a.add_state();
00091         series_set_elt_t series(a.structure().series());
00092         series.assoc(m, s_ident);
00093         a.add_series_transition(s0, s1, series);
00094       }
00095 
00096       m = *l;
00097 
00098       series_set_elt_t out_series(a.structure().series());
00099       out_series.assoc(m, s_ident);
00100 
00101       if (final)
00102       {
00103         a.unset_final(start);
00104         a.set_final(s1, out_series);
00105       }
00106       else
00107         a.add_series_transition(s1, stop, out_series);
00108 
00109       return 1;
00110     }
00111 
00112     return 0;
00113   }
00114 
00115 
00116   template <class S, class T>
00117   void realtime_words_here(Element<S, T>& res)
00118   {
00119     typedef Element<S, T> auto_t;
00120     AUTOMATON_TYPES(auto_t);
00121     typedef std::vector<hstate_t> vector_t;
00122 
00123     
00124     cut_up_here(res);
00125 
00126     vector_t tmp;
00127     tmp.reserve(res.initial().size());
00128     for_all_const_initial_states(i, res)
00129       tmp.push_back(*i);
00130     for_all(typename vector_t, i, tmp)
00131       do_realtime_words(res, hstate_t(), *i, res.get_initial(*i), true, false);
00132     tmp.clear();
00133     for_all_const_final_states(f, res)
00134       tmp.push_back(*f);
00135     for_all(typename vector_t, f, tmp)
00136       do_realtime_words(res, *f, hstate_t(), res.get_final(*f), false, true);
00137 
00138     transitions_t transitions = res.transitions();
00139     for_all_(transitions_t, e, transitions)
00140       if (do_realtime_words(res, res.src_of(*e), res.dst_of(*e),
00141                             res.series_of(*e), false, false))
00142         res.del_transition(*e);
00143   }
00144 
00145 
00146 
00147   
00148 
00149 
00150   template <class A, typename AI>
00151   bool
00152   do_is_realtime(const AutomataBase<A>&, const Element<A, AI>& a)
00153   {
00154     TIMER_SCOPED("is_realtime (automaton)");
00155     typedef Element<A, AI> automaton_t;
00156     AUTOMATON_TYPES(automaton_t);
00157     for_all_const_transitions(e, a)
00158       if (!is_support_in_alphabet(a.series_of(*e)))
00159         return false;
00160     return true;
00161   }
00162 
00163 
00164   
00165 
00166 
00167 
00168   template<typename A, typename AI>
00169   void
00170   do_realtime_here(const AutomataBase<A>&,
00171                    Element<A, AI>& a,
00172                    misc::direction_type dir = misc::backward)
00173   {
00174     realtime_words_here(a);
00175 
00176     eps_removal_here(a, dir);
00177 
00178     
00179     if (dir == misc::forward)
00180       coaccessible_here(a);
00181     else
00182       accessible_here(a);
00183   }
00184 
00185 
00186   template<typename A, typename AI>
00187   void
00188   realtime_here(Element<A, AI>& a, misc::direction_type dir)
00189   {
00190     do_realtime_here(a.structure(), a, dir);
00191   }
00192 
00193 
00194   
00195 
00196 
00197 
00198   template<typename A, typename AI>
00199   Element<A, AI>
00200   do_realtime(const AutomataBase<A>& b,
00201               const Element<A, AI>&  a,
00202               misc::direction_type dir = misc::backward)
00203   {
00204     Element<A, AI> ret(a);
00205     do_realtime_here(b, ret, dir);
00206     return ret;
00207   }
00208 
00209   template<typename A, typename AI>
00210   Element<A, AI>
00211   realtime(const Element<A, AI>& a, misc::direction_type dir)
00212   {
00213     return do_realtime(a.structure(), a, dir);
00214   }
00215 
00216 
00217 } 
00218 
00219 #endif // ! VCSN_ALGORITHMS_REALTIME_HXX