- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

# invert.hxx

    00001 // invert.hxx: this file is part of the Vaucanson project.
    00002 //
    00003 // Vaucanson, a generic library for finite state machines.
    00004 //
    00005 // Copyright (C) 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
    00018 #ifndef VCSN_ALGORITHMS_INVERT_HXX_
    00019 # define VCSN_ALGORITHMS_INVERT_HXX_
    00020
    00021 # include <map>
    00022
    00023 # include <vaucanson/automata/concept/automata_base.hh>
    00024 # include <vaucanson/automata/concept/transducer.hh>
    00025 # include <vaucanson/algebra/concept/freemonoid_product.hh>
    00026 # include <vaucanson/algebra/implementation/series/series.hh>
    00027
    00028 # include <vaucanson/misc/usual_macros.hh>
    00029
    00030 # include <vaucanson/algorithms/standard_of.hh>
    00031 # include <vaucanson/algorithms/realtime.hh>
    00032
    00033 namespace vcsn
    00034 {
    00035
    00036   /*------------------------------------.
    00037   | Specialization for RW transducers.  |
    00038   `------------------------------------*/
    00039
    00040   template<typename S, typename T>
    00041   Element<S, T>&
    00042   do_invert_rw(Element<S, T>& t,
    00043                Element<S, T>& u)
    00044   {
    00045     typedef Element<S, T> Trans_t;
    00046     typedef typename output_projection_helper<S, T>::ret Auto_t;
    00047     AUTOMATON_TYPES(Trans_t);
    00048
    00049     normalize_here(t);
    00050
    00051     std::map<hstate_t, hstate_t> map_t_u;
    00052     for_all_states (p, t)
    00053       map_t_u[*p] = u.add_state ();
    00054
    00055     initial_iterator i_it;
    00056     for (initial_iterator next = t.initial().begin(), next_end = t.initial().end();
    00057          next != next_end;)
    00058     {
    00059       //We need to store the next iterator before using the current one
    00060       //to avoid an invalid iterator after having called set_final.
    00061       //Indeed, set_final can delete the iterator if its second parameter
    00062       //is the zero of the serie.
    00063       i_it = next;
    00064       next++;
    00065       u.set_initial (map_t_u[*i_it]);
    00066     }
    00067
    00068     final_iterator f_it;
    00069     for (final_iterator next = t.final().begin(), next_end = t.final().end();
    00070          next != next_end;)
    00071     {
    00072       //We need to store the next iterator before using the current one
    00073       //to avoid an invalid iterator after having called set_final.
    00074       //Indeed, set_final can delete the iterator if its second parameter
    00075       //is the zero of the serie.
    00076       f_it = next;
    00077       next++;
    00078       u.set_final (map_t_u[*f_it]);
    00079     }
    00080
    00081     for_all_transitions (e, t)
    00082     {
    00083       semiring_elt_t exp = t.output_of(*e);
    00084
    00085       typename Auto_t::set_t auto_structure
    00086         (typename Auto_t::set_t::series_set_t
    00087          (t.structure().series().semiring()));
    00088       Auto_t auto_tmp(auto_structure);
    00089
    00090       // As the output of each transition is not supposed to be
    00091       // realtime we build the standard automaton corresponding to
    00092       // this expression
    00093       standard_of(auto_tmp, exp.value());
    00094
    00095       std::map<hstate_t, hstate_t> map_auto_u;
    00096
    00097       for_all_states (p, auto_tmp)
    00098         if (auto_tmp.is_initial (*p))
    00099           map_auto_u[*p] = map_t_u[t.src_of(*e)];
    00100         else
    00101           map_auto_u[*p] = u.add_state();
    00102
    00103       typename semiring_elt_t::semiring_elt_t
    00104         o_sm_zero (u.structure().series().semiring().semiring());
    00105       monoid_elt_t monoid_identity = u.series().monoid().vcsn_empty;
    00106
    00107       monoid_elt_t a (u.structure().series().monoid());
    00108       semiring_elt_t sm (u.structure().series().semiring());
    00109       series_set_elt_t s (u.structure().series());
    00110
    00111       for (typename Auto_t::transition_iterator f =
    00112              auto_tmp.transitions().begin();
    00113            f != auto_tmp.transitions().end();
    00114            ++f)
    00115       {
    00116         a = auto_tmp.word_of (*f);
    00117
    00118         s.assoc (a, algebra::identity_as<semiring_elt_value_t>
    00119                  ::of(u.series().semiring()));
    00120
    00121         u.add_series_transition (map_auto_u[auto_tmp.src_of(*f)],
    00122                                  map_auto_u[auto_tmp.dst_of(*f)],
    00123                                  s);
    00124       }
    00125
    00126       a = t.input_of (*e);
    00127       for (typename Auto_t::final_iterator q = auto_tmp.final().begin();
    00128            q != auto_tmp.final().end();
    00129            ++q)
    00130       {
    00131         typedef typename semiring_elt_t::semiring_elt_t output_sm_t;
    00132         typedef typename output_sm_t::value_t output_sm_value_t;
    00133
    00134         sm.assoc (a, algebra::identity_as<output_sm_value_t>
    00135                   ::of(u.series().semiring().semiring()));
    00136         s.assoc(monoid_identity, sm);
    00137         u.add_series_transition(map_auto_u[*q],
    00138                                 map_t_u[t.dst_of(*e)],
    00139                                 s);
    00140       }
    00141     }
    00142
    00143     realtime_here(u);
    00144
    00145     return u;
    00146   }
    00147
    00148
    00149   /*----------------------------------.
    00150   | Specialization for  transducers.  |
    00151   `----------------------------------*/
    00152
    00153
    00154   // Invert `label' and store the result in `res'.
    00155   template<typename S, typename T,
    00156            typename SS, typename TT>
    00157   static void invert_label(const Element<S, T>& label,
    00158                            Element<SS, TT>& res)
    00159   {
    00160     typedef Element<S, T> series_set_elt_t;
    00161     typedef typename series_set_elt_t::monoid_elt_t::value_t
    00162       res_monoid_elt_value_t;
    00163
    00164     // Invert each pair
    00165     for_all_const_(series_set_elt_t::support_t, w, label.supp())
    00166       // (u,v) -> (v,u)
    00167       res.assoc(res_monoid_elt_value_t((*w).second, (*w).first),
    00168                 label.get(*w));
    00169   }
    00170
    00171
    00172   template<typename S, typename T,
    00173            typename SS, typename TT>
    00174   Element<SS, TT>&
    00175   do_invert_tdc(const Element<S, T>& t,
    00176                 Element<SS, TT>& u)
    00177   {
    00178     typedef Element<S, T> Trans_t;
    00179     typedef Element<SS, TT> res_t;
    00180     AUTOMATON_TYPES(Trans_t);
    00181     AUTOMATON_TYPES_(res_t, res_);
    00182
    00183     std::map<hstate_t, hstate_t> map_t_u;
    00184     for_all_states (p, t)
    00185       map_t_u[*p] = u.add_state ();
    00186
    00187     // Proceed initial and final states
    00188     for_all_initial_states (p, t)
    00189       {
    00190         res_series_set_elt_t s (u.structure().series());
    00191         invert_label(t.get_initial(*p), s);
    00192         u.set_initial (map_t_u[*p], s);
    00193       }
    00194
    00195     for_all_final_states (p, t)
    00196       {
    00197         res_series_set_elt_t s (u.structure().series());
    00198         invert_label(t.get_final(*p), s);
    00199         u.set_final (map_t_u[*p], s);
    00200       }
    00201
    00202
    00203     for_all_transitions (e, t)
    00204       {
    00205         res_series_set_elt_t s (u.structure().series());
    00206         res_monoid_elt_t a (u.structure().series().monoid());
    00207
    00208         // Get the label of the current transition
    00209         series_set_elt_t label(t.structure().series());
    00210         label = t.series_of(*e);
    00211
    00212         invert_label(label, s);
    00213
    00214         u.add_series_transition(map_t_u[t.src_of(*e)],
    00215                                 map_t_u[t.dst_of(*e)],
    00216                                 s);
    00217       }
    00218
    00219     return u;
    00220   }
    00221
    00222
    00223
    00224   /*---------------------------.
    00225   | Dispatch for  tranducers.  |
    00226   `---------------------------*/
    00227
    00228   template<typename S, typename T,
    00229            typename M1, typename M2>
    00230   Element<S, T>&
    00231   do_invert_fmp(const algebra::FreeMonoidProduct<M1, M2>&,
    00232                 const Element<S, T>& t)
    00233   {
    00234     // Declaration of the inverted transducer
    00235     typedef Element<S, T> trans_t;
    00236     AUTOMATON_TYPES(trans_t);
    00237
    00238     typedef algebra::FreeMonoidProduct<
    00239       typename trans_t::series_set_t::monoid_t::second_monoid_t,
    00240       typename trans_t::series_set_t::monoid_t::first_monoid_t>
    00241       res_monoid_t;
    00242
    00243     typedef algebra::Series<typename trans_t::series_set_t::semiring_t,
    00244       res_monoid_t>
    00245       res_series_set_t;
    00246
    00247     res_monoid_t monoid(t.structure().series().monoid().second_monoid(),
    00248                         t.structure().series().monoid().first_monoid());
    00249
    00250
    00251     res_series_set_t series(t.structure().series().semiring(), monoid);
    00252
    00253     Automata<series_set_t> trans_set(series);
    00254
    00255     typedef Element< Automata<series_set_t>, T> res_trans_t;
    00256     res_trans_t* res = new res_trans_t(trans_set);
    00257
    00258     return do_invert_tdc(t, *res);
    00259   }
    00260
    00261
    00262   template<typename S, typename T,
    00263            typename SS, typename TT,
    00264            typename M1, typename M2>
    00265   Element<SS, TT>&
    00266   do_invert_fmp(const algebra::FreeMonoidProduct<M1, M2>&,
    00267                 const Element<S, T>& t,
    00268                 Element<SS, TT>& res)
    00269   {
    00270     return do_invert_tdc(t, res);
    00271   }
    00272
    00273
    00274   template<typename S, typename T>
    00275   Element<S, T>&
    00276   do_invert(const AutomataBase<S>&,
    00277             const Element<S, T>& t)
    00278   {
    00279     return do_invert_fmp(t.structure().series().monoid(), t);
    00280   }
    00281
    00282   template<typename S, typename T>
    00283   Element<S, T>&
    00284   do_invert(const AutomataBase<S>&,
    00285             const Element<S, T>& t,
    00286             Element<S, T>& res)
    00287   {
    00288     return do_invert_fmp(t.structure().series().monoid(), t, res);
    00289
    00290   }
    00291
    00292   /*-----------------------------.
    00293   | Dispatch for RW tranducers.  |
    00294   `-----------------------------*/
    00295
    00296   template<typename S, typename T>
    00297   Element<S, T>&
    00298   do_invert(const TransducerBase<S>&,
    00299             const Element<S, T>& t)
    00300   {
    00301     // Building the structure of the inverted transducer
    00302     typedef Element<S, T> Trans_t;
    00303     AUTOMATON_TYPES(Trans_t);
    00304
    00305     monoid_t o_mon_structure
    00306       (t.structure().series().monoid());
    00307     typename semiring_t::semiring_t sm_sm_structure
    00308       (t.structure().series().semiring().semiring());
    00309     typename semiring_t::monoid_t i_mon_structure
    00310       (t.structure().series().semiring().monoid());
    00311
    00312     semiring_t sm_structure (sm_sm_structure, o_mon_structure);
    00313     series_set_t ss_structure(sm_structure, i_mon_structure);
    00314
    00315     automata_set_t auto_structure(ss_structure);
    00316
    00317     Trans_t* res = new Trans_t(auto_structure);
    00318     Trans_t src(t);
    00319
    00320     do_invert_rw(src, *res);
    00321     return *res;
    00322   }
    00323
    00324
    00325   template<typename S, typename T>
    00326   Element<S, T>&
    00327   do_invert(const TransducerBase<S>&,
    00328             const Element<S, T>& t,
    00329             Element<S, T>& res)
    00330   {
    00331     Element<S, T> src(t);
    00332     return do_invert_rw(src, res);
    00333   }
    00334
    00335
    00336
    00337
    00338   /*----------.
    00339   | Facades.  |
    00340   `----------*/
    00341
    00342   template<typename S, typename T>
    00343   Element<S, T>&
    00344   invert(const Element<S, T>& t)
    00345   {
    00346     TIMER_SCOPED("invert");
    00347     return do_invert(t.structure(), t);
    00348   }
    00349
    00350   template<typename S, typename T>
    00351   void
    00352   invert(const Element<S, T>& t,
    00353          Element<S, T>& res)
    00354   {
    00355     TIMER_SCOPED("invert");
    00356     do_invert(t.structure(), t, res);
    00357   }
    00358 }
    00359
    00360 #endif // !VCSN_ALGORITHMS_INVERT_HXX_