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

Generated on Fri Jul 28 12:18:29 2006 for Vaucanson by  doxygen 1.4.6