Vaucanson 1.4
|
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 */