normalized_composition.hxx

Go to the documentation of this file.
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 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 
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     | Get initial states of the product |
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     | Processing |
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         // If the outgoing transition is of type (*, 1).
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           | Add transition.  |
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             // If the incoming transition is not of type (1, *).
00255             if (right_supp_elt.value().first !=
00256                 rhs_first_identity.value())
00257             {
00258               //  we try to connect a transition of lhs and
00259               // a transition of rhs.
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                 | Add transition.  |
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           | Add transition.  |
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 } // End of namespace vcsn.
00503 
00504 #endif // ! VCSN_ALGORITHMS_NORMALIZED_COMPOSITION_HXX

Generated on Fri Jul 28 12:18:49 2006 for Vaucanson by  doxygen 1.4.6