invert.hxx

00001 // product.hh: 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         INVERT_HXX_
00019 # define        INVERT_HXX_
00020 
00021 # include <map>
00022 
00023 # include <vaucanson/misc/usual_macros.hh>
00024 
00025 # include <vaucanson/algorithms/standard_of.hh>
00026 # include <vaucanson/algorithms/realtime.hh>
00027 
00028 namespace vcsn {
00029 
00030 
00031   /*----------------------------------.
00032   | Specialization for RW transducers |
00033   `----------------------------------*/
00034 
00035   template<typename S, typename T>
00036   Element<S, T>& do_invert_rw(Element<S, T>& t,
00037                               Element<S, T>& u)
00038   {
00039     typedef Element<S, T> Trans_t;
00040     typedef typename output_projection_helper<S, T>::ret Auto_t;
00041     AUTOMATON_TYPES(Trans_t);
00042 
00043     normalize_here(t);
00044 
00045     std::map<hstate_t, hstate_t> map_t_u;
00046     for_all_states (p, t)
00047       map_t_u[*p] = u.add_state ();
00048 
00049     for_all_initial_states (p, t)
00050       u.set_initial (map_t_u[*p]);
00051 
00052     for_all_final_states (p, t)
00053       u.set_final (map_t_u[*p]);
00054 
00055     for_all_transitions (e, t)
00056       {
00057         semiring_elt_t exp = t.output_of(*e);
00058 
00059         typename Auto_t::set_t auto_structure
00060           (typename Auto_t::set_t::series_set_t
00061            (t.structure().series().semiring()));
00062         Auto_t auto_tmp(auto_structure);
00063 
00064         // As the output of each transition is not supposed to be
00065         // realtime we build the standard automaton corresponding to
00066         // this expression
00067         standard_of(auto_tmp, exp.value());
00068 
00069         std::map<hstate_t, hstate_t> map_auto_u;
00070 
00071         for_all_states (p, auto_tmp)
00072           if (auto_tmp.is_initial (*p))
00073             map_auto_u[*p] = map_t_u[t.src_of(*e)];
00074           else
00075             map_auto_u[*p] = u.add_state();
00076 
00077         typename semiring_elt_t::semiring_elt_t
00078           o_sm_zero (u.structure().series().semiring().semiring());
00079         monoid_elt_t monoid_identity = u.series().monoid().empty_;
00080 
00081         monoid_elt_t a (u.structure().series().monoid());
00082         semiring_elt_t sm (u.structure().series().semiring());
00083         series_set_elt_t s (u.structure().series());
00084 
00085         for (typename Auto_t::transition_iterator f =
00086                auto_tmp.transitions().begin();
00087              f != auto_tmp.transitions().end();
00088              ++f)
00089         {
00090           a = auto_tmp.word_of (*f);
00091 
00092           s.assoc (a, algebra::identity_as<semiring_elt_value_t>
00093                    ::of(u.series().semiring()));
00094 
00095           u.add_series_transition (map_auto_u[auto_tmp.src_of(*f)],
00096                                    map_auto_u[auto_tmp.dst_of(*f)],
00097                                    s);
00098         }
00099 
00100         a = t.input_of (*e);
00101         for (typename Auto_t::final_iterator q = auto_tmp.final().begin();
00102              q != auto_tmp.final().end();
00103              ++q)
00104         {
00105           typedef typename semiring_elt_t::semiring_elt_t output_sm_t;
00106           typedef typename output_sm_t::value_t output_sm_value_t;
00107 
00108           sm.assoc (a, algebra::identity_as<output_sm_value_t>
00109                     ::of(u.series().semiring().semiring()));
00110           s.assoc(monoid_identity, sm);
00111           u.add_series_transition(map_auto_u[*q],
00112                                   map_t_u[t.dst_of(*e)],
00113                                   s);
00114         }
00115       }
00116 
00117     realtime_here(u);
00118 
00119     return u;
00120   }
00121 
00122 
00123 
00124   /*---------------------------.
00125   | Dispatch for RW tranducers |
00126   `---------------------------*/
00127 
00128   template<typename S, typename T>
00129   Element<S, T>&
00130   do_invert(const TransducerBase<S>&,
00131             const Element<S, T>& t)
00132   {
00133     // Building the structure of the inverted transducer
00134     typedef Element<S, T> Trans_t;
00135     AUTOMATON_TYPES(Trans_t);
00136 
00137     monoid_t o_mon_structure
00138       (t.structure().series().monoid());
00139     typename semiring_t::semiring_t sm_sm_structure
00140       (t.structure().series().semiring().semiring());
00141     typename semiring_t::monoid_t i_mon_structure
00142       (t.structure().series().semiring().monoid());
00143 
00144     semiring_t sm_structure (sm_sm_structure, o_mon_structure);
00145     series_set_t ss_structure(sm_structure, i_mon_structure);
00146 
00147     automata_set_t auto_structure(ss_structure);
00148 
00149 
00150     Trans_t* res = new Trans_t(auto_structure);
00151     Trans_t src(t);
00152 
00153     do_invert_rw(src, *res);
00154     return *res;
00155   }
00156 
00157 
00158   template<typename S, typename T>
00159   Element<S, T>&
00160   do_invert(const TransducerBase<S>&,
00161             const Element<S, T>& t,
00162             Element<S, T>& res)
00163   {
00164     Element<S, T> src(t);
00165 
00166     return do_invert_rw(src, res);
00167   }
00168 
00169 
00170 
00171 
00172   /*----------.
00173   |  Facades  |
00174   `----------*/
00175 
00176   template<typename S, typename T>
00177   Element<S, T>&
00178   invert(const Element<S, T>& t)
00179   {
00180     return do_invert(t.structure(), t);
00181   }
00182 
00183   template<typename S, typename T>
00184   void
00185   invert(const Element<S, T>& t,
00186          Element<S, T>& res)
00187   {
00188     Element<S, T> src(t);
00189 
00190     do_invert(t.structure(), src, res);
00191   }
00192 }
00193 
00194 #endif /* !INVERT_HXX_ */

Generated on Sat Jul 29 17:13:00 2006 for Vaucanson by  doxygen 1.4.6