Vaucanson 1.4
image.hxx
00001 // image.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2006, 2008, 2011 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_IMAGE_HXX
00019 # define VCSN_ALGORITHMS_IMAGE_HXX
00020 
00021 # include <vaucanson/algorithms/image.hh>
00022 # include <vaucanson/algorithms/cut_up.hh>
00023 # include <vaucanson/algorithms/projection.hh>
00024 
00025 namespace vcsn
00026 {
00027   template <typename auto_t, typename trans_t>
00028   static void
00029   do_fmp_image(const trans_t& input, auto_t& res, bool weighted)
00030   {
00031     BENCH_TASK_SCOPED("image");
00032     AUTOMATON_TYPES_(trans_t, trans_);
00033     AUTOMATON_TYPES(auto_t);
00034 
00035     trans_t fmp_trans = cut_up(input);
00036 
00037     typedef typename trans_series_set_elt_t::support_t  trans_support_t;
00038     std::map<trans_hstate_t, hstate_t>  stmap;
00039 
00040     const series_set_t& series = res.structure().series();
00041     const monoid_t& monoid = res.structure().series().monoid();
00042     const semiring_elt_t& unit = res.structure().series().semiring().wone_;
00043     const trans_monoid_t& trans_monoid =
00044       fmp_trans.structure().series().monoid();
00045 
00046     for_all_const_states(fmp_s, fmp_trans)
00047       {
00048         hstate_t s = res.add_state();
00049         stmap[*fmp_s] = s;
00050 
00051         if (fmp_trans.is_initial(*fmp_s))
00052           {
00053             const trans_series_set_elt_t trans_series_elt =
00054               fmp_trans.get_initial(*fmp_s);
00055             trans_support_t trans_supp = trans_series_elt.supp();
00056             const trans_monoid_elt_t trans_monoid_elt(trans_monoid,
00057                                                       *(trans_supp.begin()));
00058 
00059             const monoid_elt_value_t word(trans_monoid_elt.value().second);
00060 
00061             series_set_elt_t series_elt(series);
00062 
00063             series_elt.assoc(monoid_elt_t(monoid, word),
00064                              weighted ?
00065                              trans_series_elt.get(trans_monoid_elt) : unit);
00066 
00067             res.set_initial(s, series_elt);
00068           }
00069         if (fmp_trans.is_final(*fmp_s))
00070           {
00071             const trans_series_set_elt_t trans_series_elt =
00072               fmp_trans.get_final(*fmp_s);
00073             trans_support_t trans_supp = trans_series_elt.supp();
00074             const trans_monoid_elt_t trans_monoid_elt(trans_monoid,
00075                                                       *(trans_supp.begin()));
00076 
00077             const monoid_elt_value_t word(trans_monoid_elt.value().second);
00078 
00079             series_set_elt_t series_elt(series);
00080 
00081             series_elt.assoc(monoid_elt_t(monoid, word),
00082                              weighted ? trans_series_elt.get(trans_monoid_elt)
00083                              : unit);
00084             res.set_final(s, series_elt);
00085           }
00086       }
00087 
00088     for_all_const_transitions_(trans_, fmp_e, fmp_trans)
00089       {
00090         const trans_series_set_elt_t trans_series_elt =
00091           fmp_trans.series_of(*fmp_e);
00092         trans_support_t trans_supp = trans_series_elt.supp();
00093         const trans_monoid_elt_t trans_monoid_elt(trans_monoid,
00094                                                   *(trans_supp.begin()));
00095 
00096         const monoid_elt_value_t        word(trans_monoid_elt.value().second);
00097 
00098         series_set_elt_t series_elt(series);
00099 
00100         series_elt.assoc(monoid_elt_t(monoid, word),
00101                          weighted ? trans_series_elt.get(trans_monoid_elt)
00102                          : unit);
00103 
00104         res.add_series_transition(stmap[fmp_trans.src_of(*fmp_e)],
00105                                   stmap[fmp_trans.dst_of(*fmp_e)], series_elt);
00106       }
00107   }
00108 
00109 
00110   template<typename Trans_t, typename Auto_t>
00111   static void
00112   do_rw_image(const Trans_t& t,
00113               Auto_t& ret)
00114   {
00115     BENCH_TASK_SCOPED("image (transducer to automaton)");
00116     AUTOMATON_TYPES(Trans_t);
00117     AUTOMATON_TYPES_(Auto_t, auto_);
00118     std::map<hstate_t, auto_hstate_t> m;
00119 
00120     for_all_const_states(p, t)
00121       m[*p] = ret.add_state();
00122 
00123     monoid_elt_t empty =
00124       algebra::identity_as<monoid_elt_value_t>::of(t.series().monoid());
00125     typename Trans_t::series_set_elt_t id_series(t.structure().series());
00126     id_series = vcsn::algebra::
00127       identity_as<typename Trans_t::series_set_elt_value_t>::
00128       of(t.structure().series());
00129 
00130     for_all_const_initial_states(p, t)
00131     {
00132       if (t.get_initial(*p) != id_series)
00133       {
00134         auto_hstate_t tmp = ret.add_state();
00135         ret.set_initial(tmp);
00136         ret.add_series_transition(tmp, m[*p], t.get_initial(*p).get(empty));
00137       }
00138       else
00139         ret.set_initial(m[*p], t.get_initial(*p).get(empty));
00140     }
00141 
00142     for_all_const_final_states(p, t)
00143     {
00144       if (t.get_final(*p) != id_series)
00145       {
00146         auto_hstate_t tmp = ret.add_state();
00147         ret.set_final(tmp);
00148         ret.add_series_transition(m[*p], tmp, t.get_final(*p).get(empty));
00149       }
00150       else
00151         ret.set_final(m[*p], t.get_final(*p).get(empty));
00152     }
00153 
00154     for_all_const_transitions(e, t)
00155     {
00156       ret.add_series_transition(m[t.src_of(*e)],
00157                                 m[t.dst_of(*e)],
00158                                 t.output_of(*e));
00159     }
00160   }
00161 
00162 
00163   template <typename S, typename T, typename Auto_t>
00164   static
00165   typename output_projection_helper<S, T>::ret
00166   do_rw_image(const Element<S, T>& t,
00167               Auto_t& ret,
00168               std::map<typename Auto_t::hstate_t, typename T::hstate_t>& m_)
00169   {
00170     BENCH_TASK_SCOPED("image (transducer to automaton)");
00171     typedef Element<S, T>  Trans_t;
00172     AUTOMATON_TYPES(Trans_t);
00173 
00174     monoid_elt_t empty = t.series().monoid().VCSN_EMPTY_;
00175     std::map<hstate_t, hstate_t> m;
00176 
00177     for_all_const_states(p, t)
00178     {
00179       m[*p] = ret.add_state();
00180       m_[m[*p]] = *p;
00181     }
00182 
00183     for_all_const_initial_states(p, t)
00184       ret.set_initial(m[*p], t.get_initial(*p).get(empty));
00185 
00186     for_all_const_final_states(p, t)
00187       ret.set_final(m[*p], t.get_final(*p).get(empty));
00188 
00189     for_all_const_transitions(e, t)
00190       ret.add_series_transition(m[t.src_of(*e)], m[t.dst_of(*e)],
00191                                 t.output_of(*e));
00192 
00193     return ret;
00194   }
00195 
00196 
00197 
00198   /*-------------.
00199   | DISPATCHERS. |
00200   `-------------*/
00201 
00202   // Dispatchers for RW transducers.
00203   template <typename S, typename S2,
00204             typename T, typename T2,
00205             typename ST, typename M1>
00206   static void
00207   image_dispatch(const Element<S,T>& src,
00208                  const TransducerBase<ST>&,
00209                  const algebra::FreeMonoidBase<M1>&,
00210                  Element<S2, T2>& dst, bool)
00211   {
00212     do_rw_image(src, dst);
00213   }
00214 
00215   template <typename S, typename S2,
00216             typename T, typename T2,
00217             typename ST, typename M1>
00218   static void
00219   image_dispatch(const Element<S,T>& src,
00220                  const TransducerBase<ST>&,
00221                  const algebra::FreeMonoidBase<M1>&,
00222                  Element<S2, T2>& dst,
00223                  std::map<typename T::hstate_t, typename T2::hstate_t>& m)
00224   {
00225     do_rw_image(src, dst, m);
00226   }
00227 
00228   // Dispatch and build returned object for RW transducers. A map between
00229   // states of the resulting automaton and the tranducer is filled.
00230   template <typename S, typename T, typename ST>
00231   static
00232   typename output_projection_helper<S, T>::ret
00233   image_dispatch2(const Element<S,T>& src,
00234                   const TransducerBase<ST>&,
00235                   std::map<typename T::hstate_t, typename T::hstate_t>& m)
00236   {
00237     typename output_projection_helper<S, T>::ret dst =
00238         output_projection_helper<S, T>::make_output_projection_automaton(src);
00239 
00240     image_dispatch(src, src.structure(),
00241                    src.structure().series().monoid(), dst, m);
00242     return dst;
00243   }
00244 
00245   // Dispatch and build returned object for RW transducers
00246   template <typename S, typename T, typename ST>
00247   static
00248   typename output_projection_helper<S, T>::ret
00249   image_dispatch2(const Element<S,T>& src,
00250                   const TransducerBase<ST>&)
00251   {
00252     typename output_projection_helper<S, T>::ret dst =
00253         output_projection_helper<S, T>::make_output_projection_automaton(src);
00254 
00255     image_dispatch(src, src.structure(),
00256                    src.structure().series().monoid(), dst, true);
00257     return dst;
00258   }
00259 
00260   // Dispatcher for transducers
00261   template <typename S, typename S2,
00262             typename T, typename T2,
00263             typename ST, typename M1>
00264   static void
00265   image_dispatch(const Element<S,T>& src,
00266                  const AutomataBase<ST>&,
00267                  const algebra::FreeMonoidProductBase<M1>&,
00268                  Element<S2, T2>& dst, bool weighted)
00269   {
00270     do_fmp_image(src, dst, weighted);
00271   }
00272 
00273   /*---------------.
00274   | IMAGE FACADES. |
00275   `---------------*/
00276 
00277   template <typename S, typename T>
00278   void
00279   image(const Element<S, T>& src,
00280         typename output_projection_helper<S, T>::ret& dst,
00281         bool weighted)
00282   {
00283     image_dispatch(src, src.structure(),
00284                    src.structure().series().monoid(),
00285                    dst, weighted);
00286   }
00287 
00288   template <typename S, typename T>
00289   typename output_projection_helper<S, T>::ret
00290   image(const Element<S, T>& src)
00291   {
00292     return image_dispatch2(src, src.structure());
00293   }
00294 
00295   template <typename S, typename T>
00296   typename output_projection_helper<S, T>::ret
00297   image(const Element<S, T>& src,
00298         std::map<typename T::hstate_t, typename T::hstate_t>& m)
00299   {
00300     return image_dispatch2(src, src.structure(), m);
00301   }
00302 
00303 } // End of namespace vcsn.
00304 
00305 #endif      /* !VCSN_ALGORITHMS_IMAGE_HXX */