00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_NORMALIZED_COMPOSITION_HXX
00018 # define VCSN_ALGORITHMS_NORMALIZED_COMPOSITION_HXX
00019
00020
00031 # include <set>
00032 # include <queue>
00033 # include <vaucanson/algorithms/normalized_composition.hh>
00034 # include <vaucanson/algorithms/outsplitting.hh>
00035 # include <vaucanson/algebra/concept/freemonoid_product.hh>
00036 # include <vaucanson/algebra/implementation/series/series.hh>
00037 # include <vaucanson/automata/concept/automata.hh>
00038
00039
00040 namespace vcsn {
00041
00042 template <typename S, typename M1, typename M2, typename lhs_t,
00043 typename rhs_t, typename res_t>
00044 void
00045 do_b_composition(const AutomataBase<S>&,
00046 const algebra::FreeMonoidProduct<M1, M2>&,
00047 const lhs_t& lhs,
00048 const rhs_t& rhs,
00049 res_t& output,
00050 std::set<hstate_t>& lhs_states,
00051 std::set<hstate_t>& rhs_states,
00052 std::map< hstate_t, std::pair<hstate_t, hstate_t> >& m)
00053 {
00054 AUTOMATON_TYPES(res_t);
00055 AUTOMATON_TYPES_(lhs_t, lhs_);
00056 AUTOMATON_TYPES_(rhs_t, rhs_);
00057
00058 typedef std::pair<hstate_t, hstate_t> pair_hstate_t;
00059 typedef std::set<htransition_t> delta_ret_t;
00060 typedef std::map<pair_hstate_t, hstate_t> visited_t;
00061 typedef typename series_set_elt_t::support_t support_t;
00062 typedef typename lhs_series_set_elt_t::support_t lhs_support_t;
00063 typedef typename rhs_series_set_elt_t::support_t rhs_support_t;
00064
00065
00066 const series_set_t& series = output.structure().series();
00067 const monoid_t& monoid = series.monoid();
00068
00069 const lhs_series_set_t& lhs_series = lhs.structure().series();
00070 const lhs_monoid_t& lhs_monoid = lhs_series.monoid();
00071
00072 const rhs_series_set_t& rhs_series = rhs.structure().series();
00073 const rhs_monoid_t& rhs_monoid = rhs_series.monoid();
00074
00075
00076 typedef typename lhs_monoid_t::first_monoid_t
00077 lhs_first_monoid_t;
00078 typedef typename lhs_monoid_elt_value_t::first_type
00079 lhs_first_monoid_elt_value_t;
00080 typedef Element<lhs_first_monoid_t, lhs_first_monoid_elt_value_t>
00081 lhs_first_monoid_elt_t;
00082
00083 typedef typename rhs_monoid_t::first_monoid_t
00084 rhs_first_monoid_t;
00085 typedef typename rhs_monoid_elt_value_t::first_type
00086 rhs_first_monoid_elt_value_t;
00087 typedef Element<rhs_first_monoid_t, rhs_first_monoid_elt_value_t>
00088 rhs_first_monoid_elt_t;
00089
00090 typedef typename lhs_monoid_t::second_monoid_t
00091 lhs_second_monoid_t;
00092 typedef typename lhs_monoid_elt_value_t::second_type
00093 lhs_second_monoid_elt_value_t;
00094 typedef Element<lhs_second_monoid_t, lhs_second_monoid_elt_value_t>
00095 lhs_second_monoid_elt_t;
00096
00097 typedef typename rhs_monoid_t::second_monoid_t
00098 rhs_second_monoid_t;
00099 typedef typename rhs_monoid_elt_value_t::second_type
00100 rhs_second_monoid_elt_value_t;
00101 typedef Element<rhs_second_monoid_t, rhs_second_monoid_elt_value_t>
00102 rhs_second_monoid_elt_t;
00103
00104
00105
00106 lhs_first_monoid_elt_t lhs_first_identity =
00107 algebra::identity_as<lhs_first_monoid_elt_value_t>::
00108 of(lhs.structure().series().monoid().first_monoid());
00109 rhs_first_monoid_elt_t rhs_first_identity =
00110 algebra::identity_as<rhs_first_monoid_elt_value_t>::
00111 of(rhs.structure().series().monoid().first_monoid());
00112 lhs_second_monoid_elt_t lhs_second_identity =
00113 algebra::identity_as<lhs_second_monoid_elt_value_t>::
00114 of(lhs.structure().series().monoid().second_monoid());
00115 rhs_second_monoid_elt_t rhs_second_identity =
00116 algebra::identity_as<rhs_second_monoid_elt_value_t>::
00117 of(rhs.structure().series().monoid().second_monoid());
00118
00119
00120 visited_t visited;
00121 std::queue<pair_hstate_t> to_process;
00122
00123
00124
00125
00126 for_each_initial_state(lhs_s, lhs)
00127 for_each_initial_state(rhs_s, rhs)
00128 {
00129 if (lhs_states.find(*lhs_s) == lhs_states.end() or
00130 rhs_states.find(*rhs_s) == rhs_states.end())
00131 {
00132 const hstate_t new_state = output.add_state();
00133 const pair_hstate_t new_pair (*lhs_s, *rhs_s);
00134
00135 m[new_state] = new_pair;
00136 visited[new_pair] = new_state;
00137 to_process.push(new_pair);
00138 }
00139 }
00140
00141
00142
00143
00144 while (not to_process.empty())
00145 {
00146 const pair_hstate_t current_pair = to_process.front();
00147 to_process.pop();
00148
00149 const hstate_t lhs_s = current_pair.first;
00150 const hstate_t rhs_s = current_pair.second;
00151 const hstate_t current_state = visited[current_pair];
00152
00153 if (lhs.is_initial(lhs_s) and rhs.is_initial(rhs_s))
00154 {
00155 lhs_series_set_elt_t in_l = lhs.get_initial(lhs_s);
00156 rhs_series_set_elt_t in_r = rhs.get_initial(rhs_s);
00157
00158 lhs_support_t in_left_supp = in_l.supp();
00159 rhs_support_t in_right_supp = in_r.supp();
00160
00161 semiring_elt_t in_semi_elt = in_l.get(*(in_left_supp.begin())) *
00162 in_r.get(*(in_right_supp.begin()));
00163
00164 series_set_elt_t in_series_elt(series);
00165
00166 in_series_elt.assoc(monoid_elt_t(monoid,
00167 algebra::identity_as<
00168 monoid_elt_value_t>::
00169 of(monoid).value()),
00170 in_semi_elt);
00171
00172 output.set_initial(current_state, in_series_elt);
00173 }
00174
00175 if (lhs.is_final(lhs_s) and rhs.is_final(rhs_s))
00176 {
00177 lhs_series_set_elt_t out_l = lhs.get_final(lhs_s);
00178 rhs_series_set_elt_t out_r = rhs.get_final(rhs_s);
00179
00180 lhs_support_t out_left_supp = out_l.supp();
00181 rhs_support_t out_right_supp = out_r.supp();
00182
00183 semiring_elt_t out_semi_elt = out_l.get(*(out_left_supp.begin())) *
00184 out_r.get(*(out_right_supp.begin()));
00185
00186 series_set_elt_t out_series_elt(series);
00187
00188 out_series_elt.assoc(monoid_elt_t(monoid,
00189 algebra::identity_as<
00190 monoid_elt_value_t>::of(monoid)),
00191 out_semi_elt);
00192
00193
00194 output.set_final(current_state, out_series_elt);
00195 }
00196
00197 delta_ret_t transition_lhs;
00198 delta_ret_t transition_rhs;
00199 lhs.deltac(transition_lhs, lhs_s, delta_kind::transitions());
00200 rhs.deltac(transition_rhs, rhs_s, delta_kind::transitions());
00201
00202 for_all_const_(delta_ret_t, l, transition_lhs)
00203 {
00204 const lhs_series_set_elt_t left_series = lhs.series_of(*l);
00205 lhs_support_t left_supp = left_series.supp();
00206 const lhs_monoid_elt_t left_supp_elt (lhs_monoid,
00207 *(left_supp.begin()));
00208
00209
00210 if (left_supp_elt.value().second == lhs_second_identity.value())
00211 {
00212 series_set_elt_t prod_series (series);
00213 const monoid_elt_value_t word(left_supp_elt.value().first,
00214 rhs_second_identity.value());
00215 prod_series.assoc(monoid_elt_t(monoid, word),
00216 left_series.get(left_supp_elt));
00217
00218 const pair_hstate_t new_pair (lhs.dst_of(*l), rhs_s);
00219
00220
00221
00222
00223
00224 if (lhs_states.find(new_pair.first) == lhs_states.end() or
00225 rhs_states.find(new_pair.second) == rhs_states.end())
00226 {
00227 typename visited_t::const_iterator found =
00228 visited.find(new_pair);
00229 hstate_t aim;
00230 if (found == visited.end())
00231 {
00232 aim = output.add_state();
00233 visited[new_pair] = aim;
00234 m[aim] = new_pair;
00235 to_process.push(new_pair);
00236 }
00237 else
00238 aim = found->second;
00239 output.add_series_transition(current_state, aim, prod_series);
00240 }
00241
00242 }
00243 else
00244 {
00245 for_all_const_(delta_ret_t, r, transition_rhs)
00246 {
00247 const rhs_series_set_elt_t right_series =
00248 rhs.series_of(*r);
00249 rhs_support_t right_supp =
00250 right_series.supp();
00251 const rhs_monoid_elt_t right_supp_elt
00252 (rhs_monoid, *(right_supp.begin()));
00253
00254
00255 if (right_supp_elt.value().first !=
00256 rhs_first_identity.value())
00257 {
00258
00259
00260 if (left_supp_elt.value().second ==
00261 right_supp_elt.value().first)
00262 {
00263 series_set_elt_t prod_series (series);
00264 const monoid_elt_value_t word
00265 (left_supp_elt.value().first,
00266 right_supp_elt.value().second);
00267 const semiring_elt_t p =
00268 left_series.get(left_supp_elt) *
00269 right_series.get(right_supp_elt);
00270
00271 prod_series.assoc(word, p.value());
00272
00273
00274 const pair_hstate_t new_pair (lhs.dst_of(*l),
00275 rhs.dst_of(*r));
00276
00277
00278
00279
00280
00281
00282 if (lhs_states.find(new_pair.first) ==
00283 lhs_states.end()
00284 or
00285 rhs_states.find(new_pair.second) ==
00286 rhs_states.end())
00287 {
00288 typename visited_t::const_iterator found =
00289 visited.find(new_pair);
00290 hstate_t aim;
00291 if (found == visited.end())
00292 {
00293 aim = output.add_state();
00294 visited[new_pair] = aim;
00295 m[aim] = new_pair;
00296 to_process.push(new_pair);
00297 }
00298 else
00299 aim = found->second;
00300 output.add_series_transition(current_state, aim,
00301 prod_series);
00302 }
00303 }
00304 }
00305 }
00306 }
00307 }
00308
00309 for_all_const_(delta_ret_t, r, transition_rhs)
00310 {
00311 const rhs_series_set_elt_t right_series =
00312 rhs.series_of(*r);
00313 rhs_support_t right_supp =
00314 right_series.supp();
00315 const rhs_monoid_elt_t right_supp_elt
00316 (rhs_monoid, *(right_supp.begin()));
00317
00318 if (right_supp_elt.value().first ==
00319 rhs_first_identity.value())
00320 {
00321 series_set_elt_t prod_series (series);
00322 const monoid_elt_value_t word
00323 (lhs_first_identity.value(),
00324 right_supp_elt.value().second);
00325 prod_series.assoc(monoid_elt_t(monoid, word),
00326 right_series.get(right_supp_elt));
00327
00328 const pair_hstate_t new_pair (lhs_s, rhs.dst_of(*r));
00329
00330
00331
00332
00333
00334
00335 if (lhs_states.find(new_pair.first) ==
00336 lhs_states.end() or
00337 rhs_states.find(new_pair.second) ==
00338 rhs_states.end())
00339 {
00340 typename visited_t::const_iterator found =
00341 visited.find(new_pair);
00342 hstate_t aim;
00343 if (found == visited.end())
00344 {
00345 aim = output.add_state();
00346 visited[new_pair] = aim;
00347 m[aim] = new_pair;
00348 to_process.push(new_pair);
00349 }
00350 else
00351 aim = found->second;
00352 output.add_series_transition(current_state, aim,
00353 prod_series);
00354 }
00355 }
00356 }
00357 }
00358
00359 }
00360
00361
00362 template <typename S, typename M1, typename M2, typename lhs_t,
00363 typename rhs_t, typename res_t>
00364 void
00365 do_normalized_composition(const AutomataBase<S>&,
00366 const algebra::FreeMonoidProduct<M1, M2>&,
00367 const lhs_t& lhs,
00368 const rhs_t& rhs,
00369 res_t& ret)
00370 {
00371 typedef std::set<hstate_t> set_of_states_t;
00372 typedef std::map<hstate_t, std::pair<hstate_t, hstate_t> >
00373 map_of_states_t;
00374 set_of_states_t lhs_states;
00375 set_of_states_t rhs_states;
00376
00377 lhs_t lhs_cov = outsplitting(lhs, lhs_states);
00378 rhs_t rhs_cov = insplitting(rhs, rhs_states);
00379
00380 map_of_states_t m;
00381 do_b_composition(ret.structure(), ret.structure().series().monoid(),
00382 lhs_cov, rhs_cov, ret, lhs_states, rhs_states, m);
00383 }
00384
00385
00386
00387 template <typename S, typename T>
00388 void
00389 b_composition(const Element<S, T>& lhs,
00390 const Element<S, T>& rhs,
00391 Element<S, T>& ret)
00392 {
00393 typedef Element<S, T> auto_t;
00394 AUTOMATON_TYPES(auto_t);
00395
00396 typedef std::set<hstate_t> set_of_states_t;
00397 typedef std::map<hstate_t, std::pair<hstate_t, hstate_t> >
00398 map_of_states_t;
00399 set_of_states_t lhs_states;
00400 set_of_states_t rhs_states;
00401 map_of_states_t m;
00402
00403 for_each_state (s, ret)
00404 {
00405 ret.del_state (*s);
00406 }
00407 do_b_composition(ret.structure(), ret.structure().series().monoid(),
00408 lhs, rhs, ret, lhs_states, rhs_states, m);
00409 }
00410
00411
00412 template <typename S, typename T>
00413 Element<S, T>
00414 b_composition(const Element<S, T>& lhs,
00415 const Element<S, T>& rhs)
00416 {
00417 typedef Element<S, T> auto_t;
00418
00419 typedef algebra::FreeMonoidProduct<
00420 typename auto_t::series_set_t::monoid_t::first_monoid_t,
00421 typename auto_t::series_set_t::monoid_t::second_monoid_t> monoid_t;
00422
00423 typedef algebra::Series<typename auto_t::series_set_t::semiring_t,
00424 monoid_t>
00425 series_set_t;
00426
00427 monoid_t monoid(lhs.structure().series().monoid().first_monoid(),
00428 rhs.structure().series().monoid().second_monoid());
00429
00430
00431 series_set_t series(lhs.structure().series().semiring(), monoid);
00432
00433 Automata<series_set_t> aut_set(series);
00434
00435 Element< Automata<series_set_t>, T> ret(aut_set);
00436
00437 typedef std::set<hstate_t> set_of_states_t;
00438 typedef std::map<hstate_t, std::pair<hstate_t, hstate_t> >
00439 map_of_states_t;
00440 set_of_states_t lhs_states;
00441 set_of_states_t rhs_states;
00442 map_of_states_t m;
00443
00444 do_b_composition(ret.structure(), ret.structure().series().monoid(),
00445 lhs, rhs, ret, lhs_states, rhs_states, m);
00446 return ret;
00447 }
00448
00449
00450
00451 template <typename S, typename T>
00452 void
00453 normalized_composition(const Element<S, T>& lhs,
00454 const Element<S, T>& rhs,
00455 Element<S, T>& ret)
00456 {
00457 typedef Element<S,T> auto_t;
00458 AUTOMATON_TYPES(auto_t);
00459
00460 for_each_state (s, ret)
00461 {
00462 ret.del_state (*s);
00463 }
00464 do_normalized_composition(ret.structure(),
00465 ret.structure().series().monoid(),
00466 lhs, rhs, ret);
00467 }
00468
00469
00470 template <typename S, typename T>
00471 Element<S, T>
00472 normalized_composition(const Element<S, T>& lhs,
00473 const Element<S, T>& rhs)
00474 {
00475 typedef Element<S, T> auto_t;
00476
00477 typedef algebra::FreeMonoidProduct<
00478 typename auto_t::series_set_t::monoid_t::first_monoid_t,
00479 typename auto_t::series_set_t::monoid_t::second_monoid_t> monoid_t;
00480
00481 typedef algebra::Series<typename auto_t::series_set_t::semiring_t,
00482 monoid_t>
00483 series_set_t;
00484
00485 monoid_t monoid(lhs.structure().series().monoid().first_monoid(),
00486 rhs.structure().series().monoid().second_monoid());
00487
00488
00489 series_set_t series(lhs.structure().series().semiring(), monoid);
00490
00491 Automata<series_set_t> aut_set(series);
00492
00493 Element< Automata<series_set_t>, T> ret(aut_set);
00494 do_normalized_composition(ret.structure(),
00495 ret.structure().series().monoid(),
00496 lhs, rhs, ret);
00497 return ret;
00498 }
00499
00500
00501
00502 }
00503
00504 #endif // ! VCSN_ALGORITHMS_NORMALIZED_COMPOSITION_HXX