Vaucanson 1.4
|
00001 // normalized_composition.hxx: this file is part of the Vaucanson project. 00002 // 00003 // Vaucanson, a generic library for finite state machines. 00004 // 00005 // Copyright (C) 2005, 2006, 2011 The Vaucanson Group. 00006 // 00007 // This program is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU General Public License 00009 // as published by the Free Software Foundation; either version 2 00010 // of the License, or (at your option) any later version. 00011 // 00012 // The complete GNU General Public Licence Notice can be found as the 00013 // `COPYING' file in the root directory. 00014 // 00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file. 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 // - Add a transition between current_state and the state 00156 // corresponding to the pair (from,to). 00157 // - If the state (from,to) does not exist, then it is created. 00158 // - The transition is labelled by prod_series. 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 // Compute the series for an initial or a final state, on the 00199 // empty word. 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 // (i) 00234 // If the outgoing transition is of type (*, 1). 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 // (iii') 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 // If the incoming transition is not of type (1, *). 00255 if (right_supp_elt.value().first != 00256 rhs_first_identity.value()) 00257 // we try to connect a transition of lhs and 00258 // a transition of rhs. 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 // (ii) 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 | Get initial states of the product | 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 | Processing | 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 // Compose dispatchers 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 // Facade for compose 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 // Facade for unambiguous composition 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 } // vcsn 00522 00523 #endif // ! VCSN_ALGORITHMS_NORMALIZED_COMPOSITION_HXX