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, 2006 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   {
00049     typedef std::pair<hstate_t, hstate_t>       pair_hstate_t;
00051     typedef std::map<pair_hstate_t, hstate_t>   visited_t;
00053     typedef std::map<hstate_t, pair_hstate_t >  map_of_states_t;
00055     typedef std::queue<pair_hstate_t>           to_process_t;
00056 
00057     AUTOMATON_TYPES(res_t);
00058     AUTOMATON_TYPES_(lhs_t, lhs_);
00059     AUTOMATON_TYPES_(rhs_t, rhs_);
00060 
00061     typedef std::set<htransition_t>                     delta_ret_t;
00062     typedef typename series_set_elt_t::support_t        support_t;
00063     typedef typename lhs_series_set_elt_t::support_t    lhs_support_t;
00064     typedef typename rhs_series_set_elt_t::support_t    rhs_support_t;
00065 
00066     typedef typename lhs_monoid_t::first_monoid_t
00067     lhs_first_monoid_t;
00068     typedef typename lhs_monoid_elt_value_t::first_type
00069     lhs_first_monoid_elt_value_t;
00070     typedef Element<lhs_first_monoid_t, lhs_first_monoid_elt_value_t>
00071     lhs_first_monoid_elt_t;
00072 
00073     typedef typename rhs_monoid_t::first_monoid_t
00074     rhs_first_monoid_t;
00075     typedef typename rhs_monoid_elt_value_t::first_type
00076     rhs_first_monoid_elt_value_t;
00077     typedef Element<rhs_first_monoid_t, rhs_first_monoid_elt_value_t>
00078     rhs_first_monoid_elt_t;
00079 
00080     typedef typename lhs_monoid_t::second_monoid_t
00081     lhs_second_monoid_t;
00082     typedef typename lhs_monoid_elt_value_t::second_type
00083     lhs_second_monoid_elt_value_t;
00084     typedef Element<lhs_second_monoid_t, lhs_second_monoid_elt_value_t>
00085     lhs_second_monoid_elt_t;
00086 
00087     typedef typename rhs_monoid_t::second_monoid_t
00088     rhs_second_monoid_t;
00089     typedef typename rhs_monoid_elt_value_t::second_type
00090     rhs_second_monoid_elt_value_t;
00091     typedef Element<rhs_second_monoid_t, rhs_second_monoid_elt_value_t>
00092     rhs_second_monoid_elt_t;
00093 
00094     visited_t visited;
00095     to_process_t to_process;
00096     map_of_states_t m;
00097 
00098     const lhs_t&                 lhs;
00099     const rhs_t&                 rhs;
00100     res_t&                       output;
00101     std::set<hstate_t>&          lhs_black_states;
00102     std::set<hstate_t>&          rhs_black_states;
00103 
00104     const series_set_t& series;
00105     const monoid_t&     monoid;
00106 
00107     const lhs_series_set_t&     lhs_series;
00108     const lhs_monoid_t&         lhs_monoid;
00109 
00110     const rhs_series_set_t&     rhs_series;
00111     const rhs_monoid_t&         rhs_monoid;
00112 
00113     lhs_first_monoid_elt_t lhs_first_identity;
00114     rhs_first_monoid_elt_t rhs_first_identity;
00115     lhs_second_monoid_elt_t lhs_second_identity;
00116     rhs_second_monoid_elt_t rhs_second_identity;
00117 
00118     composer (const AutomataBase<S>&,
00119               const algebra::FreeMonoidProduct<M1, M2>&,
00120               const lhs_t&                 aLhs,
00121               const rhs_t&                 aRhs,
00122               res_t&                       aOutput,
00123               std::set<hstate_t>&          aLhs_states,
00124               std::set<hstate_t>&          aRhs_states)
00125       : lhs (aLhs),
00126         rhs (aRhs),
00127         output (aOutput),
00128         lhs_black_states (aLhs_states),
00129         rhs_black_states (aRhs_states),
00130 
00131         series (output.structure().series()),
00132         monoid (series.monoid()),
00133 
00134         lhs_series (lhs.structure().series()),
00135         lhs_monoid (lhs_series.monoid()),
00136 
00137         rhs_series (rhs.structure().series()),
00138         rhs_monoid (rhs_series.monoid()),
00139 
00140         lhs_first_identity (algebra::identity_as<lhs_first_monoid_elt_value_t>::
00141                             of(lhs_monoid.first_monoid())),
00142         rhs_first_identity (algebra::identity_as<rhs_first_monoid_elt_value_t>::
00143                             of(rhs_monoid.first_monoid())),
00144         lhs_second_identity (algebra::identity_as<lhs_second_monoid_elt_value_t>::
00145                              of(lhs_monoid.second_monoid())),
00146         rhs_second_identity (algebra::identity_as<rhs_second_monoid_elt_value_t>::
00147                              of(rhs_monoid.second_monoid()))
00148     {
00149     }
00150 
00151     // - Add a transition between current_state and the state
00152     //   corresponding to the pair (from,to).
00153     // - If the state (from,to) does not exist, then it is created.
00154     // - The transition is labelled by prod_series.
00155     void
00156     add_transition(const hstate_t current_state,
00157                    const hstate_t from,
00158                    const hstate_t to,
00159                    typename res_t::series_set_elt_t& prod_series)
00160     {
00161       if (lhs_black_states.find(from) == lhs_black_states.end()
00162           or rhs_black_states.find(to) == rhs_black_states.end())
00163         {
00164           const pair_hstate_t new_pair (from, to);
00165 
00166           typename visited_t::const_iterator found =
00167             visited.find(new_pair);
00168           hstate_t dst;
00169           if (found == visited.end())
00170             {
00171               dst = output.add_state();
00172               visited[new_pair] = dst;
00173               m[dst] = new_pair;
00174               to_process.push(new_pair);
00175             }
00176           else
00177             dst = found->second;
00178           output.add_series_transition(current_state, dst, prod_series);
00179         }
00180     }
00181 
00182     typename res_t::series_set_elt_t
00183     series_product (typename monoid_elt_value_t::first_type l1,
00184                     typename monoid_elt_value_t::second_type l2,
00185                     semiring_elt_t w)
00186     {
00187       typename res_t::series_set_elt_t res (series);
00188       const monoid_elt_value_t word (l1, l2);
00189       res.assoc(word, w.value());
00190       return res;
00191     }
00192 
00193 
00194     // Compute the series for an initial or a final state, on the
00195     // empty word.
00196     typename res_t::series_set_elt_t
00197     state_series (lhs_series_set_elt_t l,
00198                   rhs_series_set_elt_t r)
00199     {
00200       series_set_elt_t res(series);
00201       res.assoc(monoid_elt_t(monoid,
00202                              algebra::identity_as<monoid_elt_value_t>::
00203                              of(monoid).value()),
00204                 l.get(*l.supp().begin()) * r.get(*r.supp().begin()));
00205       return res;
00206     }
00207 
00208     void process_one_pair (const hstate_t current_state,
00209                            const hstate_t lhs_s, const hstate_t rhs_s)
00210     {
00211 
00212       if (lhs.is_initial(lhs_s) and rhs.is_initial(rhs_s))
00213         output.set_initial(current_state,
00214                            state_series (lhs.get_initial(lhs_s),
00215                                          rhs.get_initial(rhs_s)));
00216 
00217       if (lhs.is_final(lhs_s) and rhs.is_final(rhs_s))
00218         output.set_final(current_state,
00219                          state_series (lhs.get_final(lhs_s),
00220                                        rhs.get_final(rhs_s)));
00221 
00222       delta_ret_t transition_lhs;
00223       delta_ret_t transition_rhs;
00224       lhs.deltac(transition_lhs, lhs_s, delta_kind::transitions());
00225       rhs.deltac(transition_rhs, rhs_s, delta_kind::transitions());
00226 
00227       for_all_const_(delta_ret_t, l, transition_lhs)
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_all_const_(delta_ret_t, r, transition_rhs)
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_all_const_(delta_ret_t, r, transition_rhs)
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_initial_states(lhs_s, lhs)
00304         for_all_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     typedef std::set<hstate_t>                  set_of_states_t;
00346     set_of_states_t lhs_states;
00347     set_of_states_t rhs_states;
00348 
00349     composer<S, M1, M2, lhs_t, rhs_t, res_t>
00350       compose (ret.structure(), ret.structure().series().monoid(),
00351                lhs, rhs, ret, lhs_states, rhs_states);
00352     compose ();
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     typedef std::set<hstate_t>                  set_of_states_t;
00369     set_of_states_t lhs_states;
00370     set_of_states_t rhs_states;
00371 
00372     lhs_t lhs_cov = splitting::outsplitting(lhs, lhs_states);
00373     rhs_t rhs_cov = splitting::insplitting(rhs, rhs_states);
00374 
00375     composer<S, M1, M2, lhs_t, rhs_t, res_t>
00376       compose (ret.structure(), ret.structure().series().monoid(),
00377                lhs_cov, rhs_cov, ret, lhs_states, rhs_states);
00378     compose ();
00379 
00380     eps_removal_here (ret);
00381     sub_automaton_here (ret, useful_states (ret));
00382   }
00383 
00384 
00385 
00386   // Compose dispatchers
00387   template <typename S, typename M1, typename M2, typename lhs_t,
00388             typename rhs_t, typename res_t>
00389   void
00390   do_compose_dispatcher(const AutomataBase<S>&,
00391                         const algebra::FreeMonoidProduct<M1, M2>&,
00392                         SELECTOR(bool),
00393                         const lhs_t& lhs,
00394                         const rhs_t& rhs,
00395                         res_t& ret)
00396   {
00397     do_compose (ret.structure(),
00398                 ret.structure().series().monoid(),
00399                 lhs, rhs, ret);
00400   }
00401 
00402 
00403   template <typename S, typename M1, typename M2, typename lhs_t,
00404             typename rhs_t, typename res_t, typename weight_t>
00405   void
00406   do_compose_dispatcher(const AutomataBase<S>&,
00407                         const algebra::FreeMonoidProduct<M1, M2>&,
00408                         const weight_t&,
00409                         const lhs_t& lhs,
00410                         const rhs_t& rhs,
00411                         res_t& ret)
00412   {
00413     do_u_compose (ret.structure(),
00414                   ret.structure().series().monoid(),
00415                   lhs, rhs, ret);
00416   }
00417 
00418   // Facade for compose
00419 
00420   template <typename S, typename T>
00421   void
00422   compose(const Element<S, T>& lhs,
00423           const Element<S, T>& rhs,
00424           Element<S, T>& ret)
00425   {
00426     typedef Element<S, T> auto_t;
00427     AUTOMATON_TYPES(auto_t);
00428 
00429     for_all_states (s, ret)
00430       ret.del_state (*s);
00431 
00432     do_compose_dispatcher (ret.structure(),
00433                            ret.structure().series().monoid(),
00434                            SELECT(semiring_elt_value_t),
00435                            lhs, rhs, ret);
00436   }
00437 
00438 
00439 
00440   template <typename S, typename T>
00441   Element<S, T>
00442   compose(const Element<S, T>& lhs,
00443           const Element<S, T>& rhs)
00444   {
00445     typedef Element<S, T> auto_t;
00446     AUTOMATON_TYPES(auto_t);
00447 
00448     typedef algebra::FreeMonoidProduct<
00449     typename auto_t::series_set_t::monoid_t::first_monoid_t,
00450       typename auto_t::series_set_t::monoid_t::second_monoid_t> res_monoid_t;
00451 
00452     typedef algebra::Series<typename auto_t::series_set_t::semiring_t,
00453       res_monoid_t>
00454       res_series_set_t;
00455 
00456     res_monoid_t monoid(lhs.structure().series().monoid().first_monoid(),
00457                         rhs.structure().series().monoid().second_monoid());
00458 
00459 
00460     res_series_set_t series(lhs.structure().series().semiring(), monoid);
00461 
00462     Automata<series_set_t> aut_set(series);
00463 
00464     Element< Automata<series_set_t>, T> ret(aut_set);
00465     do_compose_dispatcher(ret.structure(),
00466                           ret.structure().series().monoid(),
00467                           SELECT(semiring_elt_value_t),
00468                           lhs, rhs, ret);
00469     return ret;
00470   }
00471 
00472 
00473   // Facade for unambiguous composition
00474   template <typename S, typename T>
00475   void
00476   u_compose(const Element<S, T>& lhs,
00477             const Element<S, T>& rhs,
00478             Element<S, T>& ret)
00479   {
00480     typedef Element<S, T> auto_t;
00481     AUTOMATON_TYPES(auto_t);
00482 
00483     for_all_states (s, ret)
00484       ret.del_state (*s);
00485 
00486     do_u_compose (ret.structure(),
00487                   ret.structure().series().monoid(),
00488                   lhs, rhs, ret);
00489   }
00490 
00491   template <typename S, typename T>
00492   Element<S, T>
00493   u_compose(const Element<S, T>& lhs,
00494             const Element<S, T>& rhs)
00495   {
00496     typedef Element<S, T> auto_t;
00497     AUTOMATON_TYPES(auto_t);
00498 
00499     typedef algebra::FreeMonoidProduct<
00500     typename auto_t::series_set_t::monoid_t::first_monoid_t,
00501       typename auto_t::series_set_t::monoid_t::second_monoid_t> res_monoid_t;
00502 
00503     typedef algebra::Series<typename auto_t::series_set_t::semiring_t,
00504       res_monoid_t>
00505       res_series_set_t;
00506 
00507     res_monoid_t monoid(lhs.structure().series().monoid().first_monoid(),
00508                         rhs.structure().series().monoid().second_monoid());
00509 
00510 
00511     res_series_set_t series(lhs.structure().series().semiring(), monoid);
00512 
00513     Automata<series_set_t> aut_set(series);
00514 
00515     Element< Automata<series_set_t>, T> ret(aut_set);
00516     do_u_compose(ret.structure(),
00517                  ret.structure().series().monoid(),
00518                  lhs, rhs, ret);
00519     return ret;
00520   }
00521 
00522 } // vcsn
00523 
00524 #endif // ! VCSN_ALGORITHMS_NORMALIZED_COMPOSITION_HXX

Generated on Wed Jun 13 17:00:28 2007 for Vaucanson by  doxygen 1.5.1