00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef VCSN_ALGORITHMS_RW_COMPOSITION_HXX
00019 # define VCSN_ALGORITHMS_RW_COMPOSITION_HXX
00020
00021 # include <map>
00022 # include <queue>
00023 # include <set>
00024
00025 # include <vaucanson/algorithms/rw_composition.hh>
00026 # include <vaucanson/algorithms/realtime.hh>
00027 # include <vaucanson/automata/concept/transducer.hh>
00028
00029
00030 # include <vaucanson/automata/implementation/geometry.hh>
00031 # include <vaucanson/algorithms/internal/evaluation.hh>
00032
00033 namespace vcsn
00034 {
00035 template <typename U, typename Trans_t>
00036 void
00037 do_rw_composition(const TransducerBase<U>&,
00038 const Trans_t& R,
00039 const Trans_t& S,
00040 Trans_t& T)
00041 {
00042 BENCH_TASK_SCOPED("rw_composition");
00043
00044
00045 precondition(is_realtime(S));
00046
00047
00048 AUTOMATON_TYPES(Trans_t);
00049 typedef series_set_elt_t exp_t;
00050 typedef typename series_set_elt_t::semiring_elt_t output_exp_t;
00051 typedef std::set<std::pair<hstate_t, output_exp_t> > state_exp_pair_set_t;
00052 typedef typename std::map<hstate_t, typename Trans_t::geometry_t::coords_t>::const_iterator geom_iter_t;
00053 typedef std::pair<hstate_t, hstate_t> state_pair_t;
00054 typedef std::queue<state_pair_t> state_pair_queue_t;
00055 typedef std::map<state_pair_t, hstate_t> state_pair_map_t;
00056 typedef std::set<htransition_t> set_of_transitions_t;
00057
00058
00059 state_pair_queue_t queue;
00060
00061
00062
00063
00064 state_exp_pair_set_t sep_set;
00065
00066
00067
00068
00069 state_pair_map_t Tstates;
00070
00071
00072 double xgeom;
00073 double ygeom;
00074 geom_iter_t iter;
00075
00076
00077
00078
00079
00080
00081 monoid_elt_t Ridentity = R.series().monoid().identity(SELECT(monoid_elt_value_t));
00082 monoid_elt_t Sidentity = S.series().monoid().identity(SELECT(monoid_elt_value_t));
00083 monoid_elt_t Tidentity = T.series().monoid().identity(SELECT(monoid_elt_value_t));
00084
00085 for_all_const_initial_states (p, R)
00086 {
00087
00088
00089
00090
00091 output_exp_t E = R.get_initial(*p).get(Ridentity);
00092
00093 for_all_const_initial_states (q, S)
00094 {
00095
00096
00097 output_exp_t F = S.get_initial(*q).get(Sidentity);
00098
00099
00100 sep_set.clear();
00101 partial_evaluation(E, S, *q, sep_set);
00102
00103
00104 for_all_const_(state_exp_pair_set_t, ig, sep_set)
00105 {
00106
00107 state_pair_t sp;
00108 sp.first = *p;
00109 sp.second = (*ig).first;
00110
00111 if (Tstates.find(sp) == Tstates.end())
00112 {
00113
00114
00115
00116 hstate_t new_state = T.add_state();
00117
00118
00119 iter = R.geometry().states().find(*p);
00120 if (iter != R.geometry().states().end())
00121 xgeom = (*iter).second.first;
00122 else
00123 xgeom = 0;
00124 iter = S.geometry().states().find(*q);
00125 if (iter != S.geometry().states().end())
00126 ygeom = (*iter).second.second;
00127 else
00128 ygeom = 0;
00129 T.geometry().states()[new_state] = std::make_pair(xgeom, ygeom);
00130
00131
00132 Tstates[sp] = new_state;
00133
00134
00135 series_set_elt_t new_series(T.series());
00136 new_series.assoc(Tidentity, F * ((*ig).second));
00137 T.set_initial(new_state, new_series);
00138
00139
00140 queue.push(sp);
00141 }
00142 else
00143 {
00144
00145
00146 series_set_elt_t new_series(T.series());
00147 new_series.assoc(Tidentity, T.get_initial(Tstates[sp]).get(Tidentity) + F * ((*ig).second));
00148 T.set_initial(Tstates[sp], new_series);
00149 }
00150 }
00151 }
00152 }
00153
00154
00155
00156
00157
00158
00159 while (not queue.empty())
00160 {
00161
00162 const state_pair_t sp = queue.front();
00163 queue.pop();
00164
00165 const hstate_t p = sp.first;
00166 const hstate_t q = sp.second;
00167
00168
00169 for (delta_iterator e(R.value(), p); !e.done(); e.next())
00170 {
00171 hstate_t s = R.dst_of(*e);
00172 exp_t E = R.series_of(*e);
00173
00174
00175
00176 for_all_const_(series_set_elt_t::support_t, y, E.supp())
00177 {
00178 const monoid_elt_t x(E.structure().monoid(), *y);
00179
00180
00181 sep_set.clear();
00182 partial_evaluation(E.get(x), S, q, sep_set);
00183
00184 for_all_const_(state_exp_pair_set_t, ig, sep_set)
00185 {
00186
00187 state_pair_t sp1;
00188 sp1.first = s;
00189 sp1.second = (*ig).first;
00190
00191 if (Tstates.find(sp1) == Tstates.end())
00192 {
00193
00194
00195
00196 hstate_t new_state = T.add_state();
00197
00198
00199 iter = R.geometry().states().find(sp1.first);
00200 if (iter != R.geometry().states().end())
00201 xgeom = (*iter).second.first;
00202 else
00203 xgeom = 0;
00204 iter = S.geometry().states().find(sp1.second);
00205 if (iter != S.geometry().states().end())
00206 ygeom = (*iter).second.second;
00207 else
00208 ygeom = 0;
00209 T.geometry().states()[new_state] = std::make_pair(xgeom, ygeom);
00210
00211
00212 Tstates[sp1] = new_state;
00213
00214
00215 queue.push(sp1);
00216 }
00217
00218 exp_t Gexp(R.structure().series());
00219 Gexp.assoc(x, (*ig).second);
00220 T.add_series_transition(Tstates[sp], Tstates[sp1], Gexp);
00221 }
00222 }
00223 }
00224
00225
00226 if (R.is_final(p))
00227 {
00228
00229
00230 sep_set.clear();
00231 partial_evaluation(R.get_final(p).get(Ridentity), S, q, sep_set);
00232
00233 for_all_const_(state_exp_pair_set_t, ig, sep_set)
00234 {
00235 const hstate_t r = (*ig).first;
00236 if (S.is_final(r))
00237 {
00238 series_set_elt_t new_series(T.series());
00239
00240 new_series.assoc(Tidentity, (*ig).second * S.get_final(r).get(Sidentity));
00241 T.set_final(Tstates[sp], new_series);
00242 }
00243 }
00244 }
00245 }
00246 }
00247
00248
00249 template <typename S, typename T>
00250 void
00251 rw_composition(const Element<S, T>& lhs,
00252 const Element<S, T>& rhs,
00253 Element<S, T>& ret)
00254 {
00255
00256 typedef Element<S, T> auto_t;
00257 AUTOMATON_TYPES(auto_t);
00258
00259
00260
00261
00262 precondition(&ret != &lhs);
00263 precondition(&ret != &rhs);
00264
00265
00266 for_all_states (s, ret)
00267 ret.del_state(*s);
00268
00269 do_rw_composition(lhs.structure(), lhs, rhs, ret);
00270 }
00271
00272
00273
00274 template <typename S, typename T>
00275 Element<S, T>
00276 rw_composition(const Element<S, T>& lhs, const Element<S, T>& rhs)
00277 {
00278
00279 Element<S, T> ret(lhs.structure());
00280
00281 do_rw_composition(lhs.structure(), lhs, rhs, ret);
00282 return ret;
00283 }
00284
00285 }
00286
00287 #endif // ! VCSN_ALGORITHMS_RW_COMPOSITION_HXX