backward_realtime.hxx

00001 // backward_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, 2006 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_BACKWARD_REALTIME_HXX
00018 # define VCSN_ALGORITHMS_BACKWARD_REALTIME_HXX
00019 
00020 # include <vaucanson/algorithms/backward_realtime.hh>
00021 # include <vaucanson/algorithms/cut_up.hh>
00022 
00023 # include <vaucanson/automata/concept/automata_base.hh>
00024 # include <vaucanson/algorithms/eps_removal.hh>
00025 # include <vaucanson/algorithms/accessible.hh>
00026 
00027 # include <queue>
00028 # include <set>
00029 
00030 namespace vcsn {
00031 
00032 
00033 
00034   /*--------------------------------------------.
00035   | Special treatment to cut words into letters |
00036   `--------------------------------------------*/
00037 
00038   template <class Auto, class Label>
00039   int do_realtime_words(Auto& a,
00040                         hstate_t start, hstate_t stop,
00041                         const Label& label, bool initial, bool final)
00042   {
00043     AUTOMATON_TYPES(Auto);
00044     hstate_t                    s1;
00045 
00046     semiring_elt_t s_ident =
00047       algebra::identity_as<semiring_elt_value_t>
00048       ::of(a.structure().series().semiring());
00049 
00050     monoid_elt_t m1(a.structure().series().monoid(), *label.supp().begin());
00051     monoid_elt_value_t w1 = m1.value();
00052 
00053     int cpt = 0;
00054 
00055     unsigned int size = w1.size();
00056 
00057     if (size > 1)
00058     {
00059       monoid_elt_t m(a.structure().series().monoid());
00060 
00061       semiring_elt_t s = label.get(m1);
00062       series_set_elt_t in_series(a.structure().series());
00063 
00064       m = w1.substr(cpt++, 1);
00065 
00066       in_series.assoc(m, s);
00067 
00068       if (initial)
00069       {
00070         hstate_t s0 = a.add_state();
00071         a.set_initial(s0, in_series);
00072         a.unset_initial(stop);
00073         s1 = s0;
00074       }
00075       else
00076       {
00077         hstate_t s0 = start;
00078         s1 = a.add_state();
00079         a.add_series_transition(s0, s1, in_series);
00080       }
00081 
00082       for (unsigned int i = 1; i < size - 1; ++i)
00083       {
00084         m = w1.substr(cpt++, 1);
00085         hstate_t s0 = s1;
00086         s1 = a.add_state();
00087         series_set_elt_t series(a.structure().series());
00088         series.assoc(m, s_ident);
00089         a.add_series_transition(s0, s1, series);
00090       }
00091 
00092       m = w1.substr(cpt++, 1);
00093 
00094       series_set_elt_t out_series(a.structure().series());
00095       out_series.assoc(m, s_ident);
00096 
00097       if (final)
00098       {
00099         a.unset_final(start);
00100         a.set_final(s1, out_series);
00101       }
00102       else
00103         a.add_series_transition(s1, stop, out_series);
00104 
00105       return 1;
00106     }
00107 
00108     return 0;
00109   }
00110 
00111 
00112   template <class S, class T>
00113   void realtime_words_here(Element<S, T>& res)
00114   {
00115     typedef Element<S, T> auto_t;
00116     AUTOMATON_TYPES(auto_t);
00117     typedef std::vector<hstate_t> vector_t;
00118 
00119     // perform cut-up.
00120     cut_up_here(res);
00121 
00122     transitions_t transitions = res.transitions();
00123     vector_t i_states; i_states.reserve(res.initial().size());
00124     vector_t f_states; f_states.reserve(res.final().size());
00125 
00126     for_all_initial_states(f, res)
00127       i_states.push_back(*f);
00128     for_all_final_states(i, res)
00129       f_states.push_back(*i);
00130 
00131     for_all_(vector_t, i, i_states)
00132       do_realtime_words(res, hstate_t(), *i,
00133                         res.get_initial(*i), true, false);
00134 
00135     for_all_(vector_t, f, f_states)
00136       do_realtime_words(res, *f, hstate_t(),
00137                         res.get_final(*f), false, true);
00138 
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   template <class A_, typename Auto_>
00147   void
00148   do_backward_realtime_here(const AutomataBase<A_>&, Auto_& a)
00149   {
00150     AUTOMATON_TYPES(Auto_);
00151     typedef std::set<htransition_t>                     delta_ret_t;
00152     typedef std::deque<htransition_t>                   queue_t;
00153 
00154     queue_t             to_del, origin_d;
00155     delta_ret_t         aim_d;
00156     monoid_elt_t        monoid_identity =
00157       algebra::identity_as<monoid_elt_value_t>::
00158       of(a.structure().series().monoid());
00159     semiring_elt_t      semiring_zero =
00160       algebra::zero_as<semiring_elt_value_t>::
00161       of(a.structure().series().semiring());
00162     series_set_elt_t    series_identity =
00163       algebra::identity_as<series_set_elt_value_t>::of(a.structure().series());
00164 
00165     backward_eps_removal_here(a);
00166 
00167     for (typename automaton_t::state_iterator origin = a.states().begin();
00168          origin != a.states().end();
00169          ++origin)
00170     {
00171       std::insert_iterator<queue_t> origin_i(origin_d, origin_d.begin());
00172       a.delta(origin_i, *origin, delta_kind::transitions());
00173 
00174       while (!origin_d.empty())
00175       {
00176         htransition_t d_o = origin_d.front();
00177         origin_d.pop_front();
00178         if (a.series_of(d_o).get(monoid_identity) != semiring_zero)
00179         {
00180           aim_d.clear();
00181           a.deltac(aim_d, a.dst_of(d_o), delta_kind::transitions());
00182           for (typename delta_ret_t::const_iterator d = aim_d.begin();
00183                d != aim_d.end();
00184                ++d)
00185             if (a.series_of(*d).get(monoid_identity) == semiring_zero)
00186             {
00187               bool new_transition = true;
00188               for (typename queue_t::const_iterator d__o =
00189                      origin_d.begin();
00190                    d__o != origin_d.end();
00191                    ++d__o)
00192                 if ((a.dst_of(*d__o) == a.dst_of(*d) &&
00193                      (a.label_of(*d__o) == a.label_of(*d))))
00194                 {
00195                   new_transition = false;
00196                   break;
00197                 }
00198 
00199               if (new_transition)
00200               {
00201                 htransition_t new_htransition = a.add_series_transition
00202                   (*origin,
00203                    a.dst_of(*d),
00204                    a.series_of(d_o) * a.series_of(*d));
00205                 origin_d.push_back(new_htransition);
00206               }
00207             }
00208           if (a.is_final(a.dst_of(d_o)))
00209             a.set_final(*origin);
00210         }
00211       }
00212     }
00213 
00214     for (typename automaton_t::transition_iterator e = a.transitions().begin();
00215          e != a.transitions().end();
00216          ++e)
00217       if (a.series_of(*e).get(monoid_identity) != semiring_zero)
00218         to_del.push_back(*e);
00219 
00220     while (!to_del.empty())
00221     {
00222       htransition_t e = to_del.front();
00223       to_del.pop_front();
00224       a.del_transition(e);
00225     }
00226 
00227     accessible_here(a);
00228 
00229     realtime_words_here(a);
00230   }
00231 
00232 
00233   template<typename A, typename T>
00234   void
00235   backward_realtime_here(Element<A, T>& a)
00236   {
00237     do_backward_realtime_here(a.structure(), a);
00238   }
00239 
00240   template <class A_, typename Auto_>
00241   Auto_
00242   do_backward_realtime(const AutomataBase<A_>&, const Auto_& a)
00243   {
00244     Auto_ ret(a);
00245     do_backward_realtime_here(ret.structure(), ret);
00246     return ret;
00247   }
00248 
00249   template<typename A, typename T>
00250   Element<A, T>
00251   backward_realtime(const Element<A, T>& a)
00252   {
00253     return do_backward_realtime(a.structure(), a);
00254   }
00255 
00256 } // vcsn
00257 
00258 #endif // ! VCSN_ALGORITHMS_BACKWARD_REALTIME_HXX

Generated on Sat Jul 29 17:12:58 2006 for Vaucanson by  doxygen 1.4.6