Vaucanson 1.4
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