- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# 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, 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