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 lhs_s,
00214 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 for (delta_iterator l(lhs.value(), lhs_s); ! l.done(); l.next())
00228 {
00229 const lhs_series_set_elt_t left_series = lhs.series_of(*l);
00230 const lhs_monoid_elt_t left_supp_elt (lhs_monoid,
00231 *left_series.supp().begin());
00232
00233
00234
00235 if (left_supp_elt.value().second == lhs_second_identity.value())
00236 {
00237 series_set_elt_t s =
00238 series_product (left_supp_elt.value().first,
00239 rhs_second_identity.value(),
00240 left_series.get(left_supp_elt));
00241 add_transition (current_state,
00242 lhs.dst_of(*l), rhs_s, s);
00243 }
00244
00245 else
00246 {
00247 for (delta_iterator r(rhs.value(), rhs_s); ! r.done(); r.next())
00248 {
00249 const rhs_series_set_elt_t right_series =
00250 rhs.series_of(*r);
00251 const rhs_monoid_elt_t right_supp_elt
00252 (rhs_monoid, *right_series.supp().begin());
00253
00254
00255 if (right_supp_elt.value().first !=
00256 rhs_first_identity.value())
00257
00258
00259 if (left_supp_elt.value().second ==
00260 right_supp_elt.value().first)
00261 {
00262 series_set_elt_t s =
00263 series_product (left_supp_elt.value().first,
00264 right_supp_elt.value().second,
00265 left_series.get(left_supp_elt)
00266 * right_series.get(right_supp_elt));
00267 add_transition
00268 (current_state,
00269 lhs.dst_of(*l), rhs.dst_of(*r),
00270 s);
00271 }
00272 }
00273 }
00274 }
00275
00276 for (delta_iterator r(rhs.value(), rhs_s); ! r.done(); r.next())
00277 {
00278 const rhs_series_set_elt_t right_series = rhs.series_of(*r);
00279 const rhs_monoid_elt_t right_supp_elt (rhs_monoid,
00280 *right_series.supp().begin());
00281
00282
00283 if (right_supp_elt.value().first == rhs_first_identity.value())
00284 {
00285 series_set_elt_t s =
00286 series_product (lhs_first_identity.value(),
00287 right_supp_elt.value().second,
00288 right_series.get(right_supp_elt));
00289 add_transition (current_state,
00290 lhs_s, rhs.dst_of(*r), s);
00291 }
00292 }
00293
00294 }
00295
00296
00297 void operator() ()
00298 {
00299
00300
00301
00302
00303 for_all_const_initial_states(lhs_s, lhs)
00304 for_all_const_initial_states(rhs_s, rhs)
00305 {
00306 if (lhs_black_states.find(*lhs_s) == lhs_black_states.end() or
00307 rhs_black_states.find(*rhs_s) == rhs_black_states.end())
00308 {
00309 const hstate_t new_state = output.add_state();
00310 const pair_hstate_t new_pair (*lhs_s, *rhs_s);
00311
00312 m[new_state] = new_pair;
00313 visited[new_pair] = new_state;
00314 to_process.push(new_pair);
00315 }
00316 }
00317
00318
00319
00320
00321 while (not to_process.empty())
00322 {
00323 const pair_hstate_t p = to_process.front();
00324 to_process.pop();
00325 process_one_pair (visited[p], p.first, p.second);
00326 }
00327 }
00328 };
00329
00330
00331
00334 template <typename S, typename M1, typename M2, typename lhs_t,
00335 typename rhs_t, typename res_t>
00336 void
00337 do_compose(const AutomataBase<S>&,
00338 const algebra::FreeMonoidProduct<M1, M2>&,
00339 const lhs_t& lhs,
00340 const rhs_t& rhs,
00341 res_t& ret)
00342 {
00343 AUTOMATON_TYPES(res_t);
00344
00345 std::set<typename lhs_t::hstate_t> lhs_states;
00346 std::set<typename rhs_t::hstate_t> rhs_states;
00347
00348 composer<S, M1, M2, lhs_t, rhs_t, res_t>
00349 compose (ret.structure(), ret.structure().series().monoid(),
00350 lhs, rhs, ret, lhs_states, rhs_states);
00351 compose ();
00352 eps_removal_here (ret);
00353 }
00354
00357 template <typename S, typename M1, typename M2, typename lhs_t,
00358 typename rhs_t, typename res_t>
00359 void
00360 do_u_compose(const AutomataBase<S>&,
00361 const algebra::FreeMonoidProduct<M1, M2>&,
00362 const lhs_t& lhs,
00363 const rhs_t& rhs,
00364 res_t& ret)
00365 {
00366 AUTOMATON_TYPES(res_t);
00367
00368 std::set<typename lhs_t::hstate_t> lhs_states;
00369 std::set<typename rhs_t::hstate_t> rhs_states;
00370
00371 lhs_t lhs_cov = splitting::outsplitting(lhs, lhs_states);
00372 rhs_t rhs_cov = splitting::insplitting(rhs, rhs_states);
00373
00374 composer<S, M1, M2, lhs_t, rhs_t, res_t>
00375 compose (ret.structure(), ret.structure().series().monoid(),
00376 lhs_cov, rhs_cov, ret, lhs_states, rhs_states);
00377 compose ();
00378
00379 eps_removal_here (ret);
00380 sub_automaton_here (ret, useful_states (ret));
00381 }
00382
00383
00384
00385
00386 template <typename S, typename M1, typename M2, typename lhs_t,
00387 typename rhs_t, typename res_t>
00388 void
00389 do_compose_dispatcher(const AutomataBase<S>&,
00390 const algebra::FreeMonoidProduct<M1, M2>&,
00391 SELECTOR(bool),
00392 const lhs_t& lhs,
00393 const rhs_t& rhs,
00394 res_t& ret)
00395 {
00396 do_compose (ret.structure(),
00397 ret.structure().series().monoid(),
00398 lhs, rhs, ret);
00399 }
00400
00401
00402 template <typename S, typename M1, typename M2, typename lhs_t,
00403 typename rhs_t, typename res_t, typename weight_t>
00404 void
00405 do_compose_dispatcher(const AutomataBase<S>&,
00406 const algebra::FreeMonoidProduct<M1, M2>&,
00407 const weight_t&,
00408 const lhs_t& lhs,
00409 const rhs_t& rhs,
00410 res_t& ret)
00411 {
00412 do_u_compose (ret.structure(),
00413 ret.structure().series().monoid(),
00414 lhs, rhs, ret);
00415 }
00416
00417
00418
00419 template <typename S, typename T>
00420 void
00421 compose(const Element<S, T>& lhs,
00422 const Element<S, T>& rhs,
00423 Element<S, T>& ret)
00424 {
00425 typedef Element<S, T> auto_t;
00426 AUTOMATON_TYPES(auto_t);
00427
00428 for_all_states (s, ret)
00429 ret.del_state (*s);
00430
00431 do_compose_dispatcher (ret.structure(),
00432 ret.structure().series().monoid(),
00433 SELECT(semiring_elt_value_t),
00434 lhs, rhs, ret);
00435 }
00436
00437
00438
00439 template <typename S, typename T>
00440 Element<S, T>
00441 compose(const Element<S, T>& lhs,
00442 const Element<S, T>& rhs)
00443 {
00444 typedef Element<S, T> auto_t;
00445 AUTOMATON_TYPES(auto_t);
00446
00447 typedef algebra::FreeMonoidProduct<
00448 typename auto_t::series_set_t::monoid_t::first_monoid_t,
00449 typename auto_t::series_set_t::monoid_t::second_monoid_t> res_monoid_t;
00450
00451 typedef algebra::Series<typename auto_t::series_set_t::semiring_t,
00452 res_monoid_t>
00453 res_series_set_t;
00454
00455 res_monoid_t monoid(lhs.structure().series().monoid().first_monoid(),
00456 rhs.structure().series().monoid().second_monoid());
00457
00458
00459 res_series_set_t series(lhs.structure().series().semiring(), monoid);
00460
00461 Automata<series_set_t, kind_t> aut_set(series);
00462
00463 Element< Automata<series_set_t, kind_t>, T> ret(aut_set);
00464 do_compose_dispatcher(ret.structure(),
00465 ret.structure().series().monoid(),
00466 SELECT(semiring_elt_value_t),
00467 lhs, rhs, ret);
00468 return ret;
00469 }
00470
00471
00472
00473 template <typename S, typename T>
00474 void
00475 u_compose(const Element<S, T>& lhs,
00476 const Element<S, T>& rhs,
00477 Element<S, T>& ret)
00478 {
00479 typedef Element<S, T> auto_t;
00480 AUTOMATON_TYPES(auto_t);
00481
00482 for_all_states (s, ret)
00483 ret.del_state (*s);
00484
00485 do_u_compose (ret.structure(),
00486 ret.structure().series().monoid(),
00487 lhs, rhs, ret);
00488 }
00489
00490 template <typename S, typename T>
00491 Element<S, T>
00492 u_compose(const Element<S, T>& lhs,
00493 const Element<S, T>& rhs)
00494 {
00495 typedef Element<S, T> auto_t;
00496 AUTOMATON_TYPES(auto_t);
00497
00498 typedef algebra::FreeMonoidProduct<
00499 typename auto_t::series_set_t::monoid_t::first_monoid_t,
00500 typename auto_t::series_set_t::monoid_t::second_monoid_t> res_monoid_t;
00501
00502 typedef algebra::Series<typename auto_t::series_set_t::semiring_t,
00503 res_monoid_t>
00504 res_series_set_t;
00505
00506 res_monoid_t monoid(lhs.structure().series().monoid().first_monoid(),
00507 rhs.structure().series().monoid().second_monoid());
00508
00509
00510 res_series_set_t series(lhs.structure().series().semiring(), monoid);
00511
00512 Automata<series_set_t, kind_t> aut_set(series);
00513
00514 Element< Automata<series_set_t, kind_t>, T> ret(aut_set);
00515 do_u_compose(ret.structure(),
00516 ret.structure().series().monoid(),
00517 lhs, rhs, ret);
00518 return ret;
00519 }
00520
00521 }
00522
00523 #endif // ! VCSN_ALGORITHMS_NORMALIZED_COMPOSITION_HXX