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

Generated on Thu Oct 9 20:22:40 2008 for Vaucanson by  doxygen 1.5.1