Vaucanson 1.4
realtime.hxx
00001 // realtime.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
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   | do_realtime_words.  |
00036   `--------------------*/
00037 
00038   template <class Auto>
00039   void do_realtime_words(Auto& a)
00040   {
00041     AUTOMATON_TYPES(Auto);
00042     hstate_t                    s1;
00043     semiring_elt_t              s_ident = algebra::identity_as<semiring_elt_value_t>
00044       ::of(a.structure().series().semiring());
00045 
00046     typedef std::vector<htransition_t> transition_vector_t;
00047     transitions_t transitions = a.transitions();
00048     transition_vector_t tmp_trans;
00049     for_all_(transitions_t, e, transitions)
00050       tmp_trans.push_back(*e);
00051 
00052     for_all(typename transition_vector_t, e, tmp_trans)
00053     {
00054       hstate_t start = a.src_of(*e);
00055       hstate_t stop = a.dst_of(*e);
00056       series_set_elt_t label = a.series_of(*e);
00057 
00058       assert(label.supp().begin() != label.supp().end());
00059 
00060       monoid_elt_t m1(a.structure().series().monoid(), *label.supp().begin());
00061       monoid_elt_value_t w1 = m1.value();
00062       unsigned int size = m1.length();
00063 
00064       if (size > 1)
00065       {
00066         monoid_elt_t m(a.structure().series().monoid());
00067 
00068         semiring_elt_t s = label.get(m1);
00069         series_set_elt_t in_series(a.structure().series());
00070         typename monoid_elt_t::iterator l = m1.begin();
00071 
00072         m = *l;
00073 
00074         in_series.assoc(m, s);
00075 
00076         s1 = a.add_state();
00077         a.add_series_transition(start, s1, in_series);
00078 
00079         l++;
00080         for (typename monoid_elt_t::iterator end = m1.begin() + (size - 1);
00081              l != end; ++l)
00082         {
00083           m = *l;
00084           hstate_t s0 = s1;
00085           s1 = a.add_state();
00086           series_set_elt_t series(a.structure().series());
00087           series.assoc(m, s_ident);
00088           a.add_series_transition(s0, s1, series);
00089         }
00090 
00091         m = *l;
00092 
00093         series_set_elt_t out_series(a.structure().series());
00094         out_series.assoc(m, s_ident);
00095 
00096         a.add_series_transition(s1, stop, out_series);
00097         a.del_transition(*e);
00098       }
00099     }
00100   }
00101 
00102 
00103   template <class S, class T>
00104   void realtime_words_here(Element<S, T>& res)
00105   {
00106     typedef Element<S, T> auto_t;
00107     AUTOMATON_TYPES(auto_t);
00108     typedef std::vector<hstate_t> state_vector_t;
00109     typedef std::vector<htransition_t> transition_vector_t;
00110     state_vector_t tmp;
00111 
00112     // perform cut-up.
00113     cut_up_here(res);
00114 
00115     // Remove any labels from initial arrows.
00116     tmp.reserve(res.initial().size());
00117     for_all_const_initial_states(i, res)
00118       tmp.push_back(*i);
00119     for_all(typename state_vector_t, i, tmp)
00120     {
00121       series_set_elt_t l = res.get_initial(*i);
00122       assert(l.supp().begin() != l.supp().end());
00123       monoid_elt_t m(res.structure().series().monoid(), *l.supp().begin());
00124       if (m.length() > 0)
00125       {
00126         hstate_t s = res.add_state();
00127         res.add_series_transition(s, *i, l);
00128         res.set_initial(s);
00129         res.unset_initial(*i);
00130       }
00131     }
00132     tmp.clear();
00133 
00134     // Remove any labels from final arrows.
00135     tmp.reserve(res.final().size());
00136     for_all_const_final_states(f, res)
00137       tmp.push_back(*f);
00138     for_all(typename state_vector_t, f, tmp)
00139     {
00140       series_set_elt_t l = res.get_final(*f);
00141       assert(l.supp().begin() != l.supp().end());
00142       monoid_elt_t m(res.structure().series().monoid(), *l.supp().begin());
00143       if (m.length() > 0)
00144       {
00145         hstate_t s = res.add_state();
00146         res.add_series_transition(*f, s, l);
00147         res.set_final(s);
00148         res.unset_final(*f);
00149       }
00150     }
00151 
00152     // Make the transitions realtime (now includes any former initial
00153     // or final labels).
00154     do_realtime_words(res);
00155   }
00156 
00157 
00158 
00159   /*--------------.
00160   | is_realtime.  |
00161   `--------------*/
00162   template <class A, typename AI>
00163   bool
00164   do_is_realtime(const AutomataBase<A>&, const Element<A, AI>& a)
00165   {
00166     BENCH_TASK_SCOPED("is_realtime (automaton)");
00167     typedef Element<A, AI> automaton_t;
00168     AUTOMATON_TYPES(automaton_t);
00169     for_all_const_initial_states(e, a)
00170       {
00171         series_set_elt_t l = a.get_initial(*e);
00172         if (l.supp().size() > 1)
00173           return false;
00174         // We assume that an initial transition cannot be labeled by
00175         // the empty series.  In other words, l.supp().size() >= 1.
00176         assertion(l.supp().size() == 1);
00177         monoid_elt_t m(a.structure().series().monoid(), *l.supp().begin());
00178         if (m.length() > 0)
00179           return false;
00180       }
00181     for_all_const_final_states(e, a)
00182       {
00183         series_set_elt_t l = a.get_final(*e);
00184         if (l.supp().size() > 1)
00185           return false;
00186         // We assume that a final transition cannot be labeled by
00187         // the empty series.  In other words, l.supp().size() >= 1.
00188         assertion(l.supp().size() == 1);
00189         monoid_elt_t m(a.structure().series().monoid(), *l.supp().begin());
00190         if (m.length() > 0)
00191           return false;
00192       }
00193     for_all_const_transitions(e, a)
00194       if (!is_support_in_alphabet(a.series_of(*e)))
00195         return false;
00196     return true;
00197   }
00198 
00199 
00200   /*--------------.
00201   | realtime_here. |
00202   `--------------*/
00203 
00204   template<typename A, typename AI>
00205   void
00206   do_realtime_here(const AutomataBase<A>&,
00207                    Element<A, AI>& a,
00208                    misc::direction_type dir = misc::backward)
00209   {
00210     realtime_words_here(a);
00211 
00212     eps_removal_here(a, dir);
00213 
00214     // FIXME: This is not wanted.  See #121.
00215     if (dir == misc::forward)
00216       coaccessible_here(a);
00217     else
00218       accessible_here(a);
00219   }
00220 
00221 
00222   template<typename A, typename AI>
00223   void
00224   realtime_here(Element<A, AI>& a, misc::direction_type dir)
00225   {
00226     do_realtime_here(a.structure(), a, dir);
00227   }
00228 
00229 
00230   /*-----------.
00231   | realtime.  |
00232   `-----------*/
00233 
00234   template<typename A, typename AI>
00235   Element<A, AI>
00236   do_realtime(const AutomataBase<A>& b,
00237               const Element<A, AI>&  a,
00238               misc::direction_type dir = misc::backward)
00239   {
00240     Element<A, AI> ret(a);
00241     do_realtime_here(b, ret, dir);
00242     return ret;
00243   }
00244 
00245   template<typename A, typename AI>
00246   Element<A, AI>
00247   realtime(const Element<A, AI>& a, misc::direction_type dir)
00248   {
00249     return do_realtime(a.structure(), a, dir);
00250   }
00251 
00252 
00253 } // vcsn
00254 
00255 #endif // ! VCSN_ALGORITHMS_REALTIME_HXX