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