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