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

- File List
- File Members

# outsplitting.hxx

Go to the documentation of this file.

    00001 // outsplitting.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_OUTSPLITTING_HXX
    00018 # define VCSN_ALGORITHMS_OUTSPLITTING_HXX
    00019
    00020
    00031 # include <vaucanson/algorithms/internal/outsplitting.hh>
    00032 # include <vaucanson/algorithms/accessible.hh>
    00033 # include <vaucanson/algebra/implementation/series/series.hh>
    00034 # include <vaucanson/algebra/concept/freemonoid_product.hh>
    00035
    00036 namespace vcsn {
    00037   namespace splitting {
    00038
    00042
    00043     template <typename S, typename M1, typename M2, typename Auto_t>
    00044     Auto_t
    00045     do_outsplitting(const AutomataBase<S>&,
    00046                     const algebra::FreeMonoidProduct<M1, M2>&,
    00047                     const Auto_t& aut,
    00048                     std::set<typename Auto_t::hstate_t>& m)
    00049     {
    00050       AUTOMATON_TYPES(Auto_t);
    00051
    00052       typedef typename series_set_elt_t::support_t      support_t;
    00053
    00054       typedef typename monoid_t::second_monoid_t        second_monoid_t;
    00055
    00056       typedef typename monoid_elt_value_t::second_type
    00057         second_monoid_elt_value_t;
    00058       typedef Element<second_monoid_t, second_monoid_elt_value_t>
    00059         second_monoid_elt_t;
    00060
    00061       typedef std::list<htransition_t>                  set_of_transitions_t;
    00062
    00063
    00064
    00065       second_monoid_elt_t second_identity =
    00066         algebra::identity_as<second_monoid_elt_value_t>::
    00067         of(aut.structure().series().monoid().second_monoid());
    00068
    00069       Auto_t res(aut);
    00070
    00071       const series_set_t&       series   = res.structure().series();
    00072       const monoid_t&   monoid   = series.monoid();
    00073
    00074
    00075
    00076       for_all_states(s, res)
    00077         {
    00078           bool eps_out = false;
    00079           bool other_out = false;
    00080           bool diff = false;
    00081
    00082           // Test whether there are different types of outgoing transitions.
    00083
    00084           set_of_transitions_t transitions;
    00085           for (delta_iterator e(res.value(), *s); ! e.done(); e.next())
    00086             transitions.push_back(*e);
    00087           for_all_const_(set_of_transitions_t, e, transitions)
    00088             {
    00089               const series_set_elt_t    series  = res.series_of(*e);
    00090               support_t                 supp = series.supp();
    00091               const monoid_elt_t                supp_elt (monoid, *(supp.begin()));
    00092
    00093               if (supp_elt.value().second == second_identity.value())
    00094                 eps_out = true;
    00095               else
    00096                 other_out = true;
    00097               if (eps_out and other_out)
    00098                 {
    00099                   diff = true;
    00100                   break;
    00101                 }
    00102             }
    00103
    00104           if (eps_out and not diff)
    00105             m.insert(*s);
    00106
    00107           // If there are different types of outgoing transitions.
    00108           if (diff)
    00109             {
    00110               hstate_t s2 = res.add_state();
    00111               if (res.is_initial(*s))
    00112                 res.set_initial(s2, res.get_initial(*s));
    00113
    00114               set_of_transitions_t in_transitions;
    00115               for (rdelta_iterator e(res.value(), *s); ! e.done(); e.next())
    00116                 in_transitions.push_back(*e);
    00117
    00118               for_all_(set_of_transitions_t, e, in_transitions)
    00119                 res.add_series_transition(res.src_of(*e), s2, res.series_of(*e));
    00120
    00121               for_all_const_(set_of_transitions_t, e, transitions)
    00122                 {
    00123                   const series_set_elt_t        series  = res.series_of(*e);
    00124                   support_t             supp = series.supp();
    00125                   const monoid_elt_t    supp_elt (monoid, *(supp.begin()));
    00126
    00127                   if (supp_elt.value().second == second_identity.value())
    00128                     {
    00129                       res.add_series_transition(s2, res.dst_of(*e), res.series_of(*e));
    00130                       res.del_transition(*e);
    00131                     }
    00132                 }
    00133               m.insert(s2);
    00134             }
    00135         }
    00136       return coaccessible(res);
    00137     }
    00138
    00139
    00143
    00144     template <typename S, typename M1, typename M2, typename Auto_t>
    00145     Auto_t
    00146     do_insplitting(const AutomataBase<S>&,
    00147                    const algebra::FreeMonoidProduct<M1, M2>&,
    00148                    const Auto_t& aut,
    00149                    std::set<typename Auto_t::hstate_t>& m)
    00150     {
    00151       AUTOMATON_TYPES(Auto_t);
    00152
    00153       typedef typename series_set_elt_t::support_t      support_t;
    00154
    00155       typedef typename monoid_t::first_monoid_t first_monoid_t;
    00156
    00157       typedef typename monoid_elt_value_t::first_type
    00158         first_monoid_elt_value_t;
    00159       typedef Element<first_monoid_t, first_monoid_elt_value_t>
    00160         first_monoid_elt_t;
    00161
    00162       typedef std::list<htransition_t>                  set_of_transitions_t;
    00163
    00164
    00165
    00166       first_monoid_elt_t first_identity =
    00167         algebra::identity_as<first_monoid_elt_value_t>::
    00168         of(aut.structure().series().monoid().first_monoid());
    00169
    00170       Auto_t res(aut);
    00171
    00172       const series_set_t&       series   = res.structure().series();
    00173       const monoid_t&   monoid   = series.monoid();
    00174
    00175
    00176
    00177       for_all_states(s, res)
    00178         {
    00179           bool eps_in = false;
    00180           bool other_in = false;
    00181           bool diff = false;
    00182
    00183           // Test whether there are different types of incoming transitions.
    00184
    00185           set_of_transitions_t transitions;
    00186           for (rdelta_iterator e(res.value(), *s); ! e.done(); e.next())
    00187             transitions.push_back(*e);
    00188           for_all_const_(set_of_transitions_t, e, transitions)
    00189             {
    00190               const series_set_elt_t    series  = res.series_of(*e);
    00191               support_t                 supp = series.supp();
    00192               const monoid_elt_t                supp_elt (monoid, *(supp.begin()));
    00193
    00194               if (supp_elt.value().first == first_identity.value())
    00195                 eps_in = true;
    00196               else
    00197                 other_in = true;
    00198               if (eps_in and other_in)
    00199                 {
    00200                   diff = true;
    00201                   break;
    00202                 }
    00203             }
    00204
    00205           if (eps_in and not diff)
    00206             m.insert(*s);
    00207
    00208           // If there are different types of incoming transitions.
    00209           if (diff)
    00210             {
    00211               hstate_t s2 = res.add_state();
    00212               if (res.is_final(*s))
    00213                 res.set_final(s2, res.get_final(*s));
    00214
    00215               set_of_transitions_t out_transitions;
    00216               for (delta_iterator e(res.value(), *s); ! e.done(); e.next())
    00217                 out_transitions.push_back(*e);
    00218
    00219               for_all_(set_of_transitions_t, e, out_transitions)
    00220                 res.add_series_transition(s2, res.dst_of(*e), res.series_of(*e));
    00221
    00222               for_all_const_(set_of_transitions_t, e, transitions)
    00223                 {
    00224                   const series_set_elt_t        series  = res.series_of(*e);
    00225                   support_t             supp = series.supp();
    00226                   const monoid_elt_t    supp_elt (monoid, *(supp.begin()));
    00227
    00228                   if (supp_elt.value().first == first_identity.value())
    00229                     {
    00230                       res.add_series_transition(res.src_of(*e), s2,
    00231                                                 res.series_of(*e));
    00232                       res.del_transition(*e);
    00233                     }
    00234                 }
    00235               m.insert(s2);
    00236             }
    00237         }
    00238       return res;
    00239     }
    00240
    00241
    00242     template <typename S, typename T>
    00243     Element<S, T>
    00244     outsplitting(const Element<S, T>& aut,
    00245                  std::set<typename T::hstate_t>& states)
    00246     {
    00247       return do_outsplitting(aut.structure(),
    00248                              aut.structure().series().monoid(),
    00249                              aut,
    00250                              states);
    00251     }
    00252
    00253
    00254     template <typename S, typename T>
    00255     Element<S, T>
    00256     insplitting(const Element<S, T>& aut,
    00257                 std::set<typename T::hstate_t>& states)
    00258     {
    00259       return do_insplitting(aut.structure(),
    00260                             aut.structure().series().monoid(),
    00261                             aut,
    00262                             states);
    00263     }
    00264
    00265
    00266
    00267     template <typename S, typename T>
    00268     Element<S, T>
    00269     outsplitting(const Element<S, T>& aut)
    00270     {
    00271       std::set<typename T::hstate_t>            states;
    00272       return do_outsplitting(aut.structure(),
    00273                              aut.structure().series().monoid(),
    00274                              aut,
    00275                              states);
    00276     }
    00277
    00278
    00279     template <typename S, typename T>
    00280     Element<S, T>
    00281     insplitting(const Element<S, T>& aut)
    00282     {
    00283       std::set<typename T::hstate_t>            states;
    00284       return do_insplitting(aut.structure(),
    00285                             aut.structure().series().monoid(),
    00286                             aut,
    00287                             states);
    00288     }
    00289   }
    00290 } // End of namespace vcsn.
    00291
    00292 #endif // ! VCSN_ALGORITHMS_OUTSPLITTING_HXX