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 }
00353
00356 template <typename S, typename M1, typename M2, typename lhs_t,
00357 typename rhs_t, typename res_t>
00358 void
00359 do_u_compose(const AutomataBase<S>&,
00360 const algebra::FreeMonoidProduct<M1, M2>&,
00361 const lhs_t& lhs,
00362 const rhs_t& rhs,
00363 res_t& ret)
00364 {
00365 AUTOMATON_TYPES(res_t);
00366
00367 std::set<typename lhs_t::hstate_t> lhs_states;
00368 std::set<typename rhs_t::hstate_t> rhs_states;
00369
00370 lhs_t lhs_cov = splitting::outsplitting(lhs, lhs_states);
00371 rhs_t rhs_cov = splitting::insplitting(rhs, rhs_states);
00372
00373 composer<S, M1, M2, lhs_t, rhs_t, res_t>
00374 compose (ret.structure(), ret.structure().series().monoid(),
00375 lhs_cov, rhs_cov, ret, lhs_states, rhs_states);
00376 compose ();
00377
00378 eps_removal_here (ret);
00379 sub_automaton_here (ret, useful_states (ret));
00380 }
00381
00382
00383
00384
00385 template <typename S, typename M1, typename M2, typename lhs_t,
00386 typename rhs_t, typename res_t>
00387 void
00388 do_compose_dispatcher(const AutomataBase<S>&,
00389 const algebra::FreeMonoidProduct<M1, M2>&,
00390 SELECTOR(bool),
00391 const lhs_t& lhs,
00392 const rhs_t& rhs,
00393 res_t& ret)
00394 {
00395 do_compose (ret.structure(),
00396 ret.structure().series().monoid(),
00397 lhs, rhs, ret);
00398 }
00399
00400
00401 template <typename S, typename M1, typename M2, typename lhs_t,
00402 typename rhs_t, typename res_t, typename weight_t>
00403 void
00404 do_compose_dispatcher(const AutomataBase<S>&,
00405 const algebra::FreeMonoidProduct<M1, M2>&,
00406 const weight_t&,
00407 const lhs_t& lhs,
00408 const rhs_t& rhs,
00409 res_t& ret)
00410 {
00411 do_u_compose (ret.structure(),
00412 ret.structure().series().monoid(),
00413 lhs, rhs, ret);
00414 }
00415
00416
00417
00418 template <typename S, typename T>
00419 void
00420 compose(const Element<S, T>& lhs,
00421 const Element<S, T>& rhs,
00422 Element<S, T>& ret)
00423 {
00424 typedef Element<S, T> auto_t;
00425 AUTOMATON_TYPES(auto_t);
00426
00427 for_all_states (s, ret)
00428 ret.del_state (*s);
00429
00430 do_compose_dispatcher (ret.structure(),
00431 ret.structure().series().monoid(),
00432 SELECT(semiring_elt_value_t),
00433 lhs, rhs, ret);
00434 }
00435
00436
00437
00438 template <typename S, typename T>
00439 Element<S, T>
00440 compose(const Element<S, T>& lhs,
00441 const Element<S, T>& rhs)
00442 {
00443 typedef Element<S, T> auto_t;
00444 AUTOMATON_TYPES(auto_t);
00445
00446 typedef algebra::FreeMonoidProduct<
00447 typename auto_t::series_set_t::monoid_t::first_monoid_t,
00448 typename auto_t::series_set_t::monoid_t::second_monoid_t> res_monoid_t;
00449
00450 typedef algebra::Series<typename auto_t::series_set_t::semiring_t,
00451 res_monoid_t>
00452 res_series_set_t;
00453
00454 res_monoid_t monoid(lhs.structure().series().monoid().first_monoid(),
00455 rhs.structure().series().monoid().second_monoid());
00456
00457
00458 res_series_set_t series(lhs.structure().series().semiring(), monoid);
00459
00460 Automata<series_set_t, kind_t> aut_set(series);
00461
00462 Element< Automata<series_set_t, kind_t>, T> ret(aut_set);
00463 do_compose_dispatcher(ret.structure(),
00464 ret.structure().series().monoid(),
00465 SELECT(semiring_elt_value_t),
00466 lhs, rhs, ret);
00467 return ret;
00468 }
00469
00470
00471
00472 template <typename S, typename T>
00473 void
00474 u_compose(const Element<S, T>& lhs,
00475 const Element<S, T>& rhs,
00476 Element<S, T>& ret)
00477 {
00478 typedef Element<S, T> auto_t;
00479 AUTOMATON_TYPES(auto_t);
00480
00481 for_all_states (s, ret)
00482 ret.del_state (*s);
00483
00484 do_u_compose (ret.structure(),
00485 ret.structure().series().monoid(),
00486 lhs, rhs, ret);
00487 }
00488
00489 template <typename S, typename T>
00490 Element<S, T>
00491 u_compose(const Element<S, T>& lhs,
00492 const Element<S, T>& rhs)
00493 {
00494 typedef Element<S, T> auto_t;
00495 AUTOMATON_TYPES(auto_t);
00496
00497 typedef algebra::FreeMonoidProduct<
00498 typename auto_t::series_set_t::monoid_t::first_monoid_t,
00499 typename auto_t::series_set_t::monoid_t::second_monoid_t> res_monoid_t;
00500
00501 typedef algebra::Series<typename auto_t::series_set_t::semiring_t,
00502 res_monoid_t>
00503 res_series_set_t;
00504
00505 res_monoid_t monoid(lhs.structure().series().monoid().first_monoid(),
00506 rhs.structure().series().monoid().second_monoid());
00507
00508
00509 res_series_set_t series(lhs.structure().series().semiring(), monoid);
00510
00511 Automata<series_set_t, kind_t> aut_set(series);
00512
00513 Element< Automata<series_set_t, kind_t>, T> ret(aut_set);
00514 do_u_compose(ret.structure(),
00515 ret.structure().series().monoid(),
00516 lhs, rhs, ret);
00517 return ret;
00518 }
00519
00520 }
00521
00522 #endif // ! VCSN_ALGORITHMS_NORMALIZED_COMPOSITION_HXX