00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00083
00084 set_of_transitions_t transitions;
00085 res.deltac(transitions, *s, delta_kind::transitions());
00086 for_all_const_(set_of_transitions_t, e, transitions)
00087 {
00088 const series_set_elt_t series = res.series_of(*e);
00089 support_t supp = series.supp();
00090 const monoid_elt_t supp_elt (monoid, *(supp.begin()));
00091
00092 if (supp_elt.value().second == second_identity.value())
00093 eps_out = true;
00094 else
00095 other_out = true;
00096 if (eps_out and other_out)
00097 {
00098 diff = true;
00099 break;
00100 }
00101 }
00102
00103 if (eps_out and not diff)
00104 m.insert(*s);
00105
00106
00107 if (diff)
00108 {
00109 hstate_t s2 = res.add_state();
00110 if (res.is_initial(*s))
00111 res.set_initial(s2, res.get_initial(*s));
00112
00113 set_of_transitions_t in_transitions;
00114 res.rdeltac(in_transitions, *s, delta_kind::transitions());
00115
00116 for_all_(set_of_transitions_t, e, in_transitions)
00117 res.add_series_transition(res.src_of(*e), s2, res.series_of(*e));
00118
00119 for_all_const_(set_of_transitions_t, e, transitions)
00120 {
00121 const series_set_elt_t series = res.series_of(*e);
00122 support_t supp = series.supp();
00123 const monoid_elt_t supp_elt (monoid, *(supp.begin()));
00124
00125 if (supp_elt.value().second == second_identity.value())
00126 {
00127 res.add_series_transition(s2, res.dst_of(*e), res.series_of(*e));
00128 res.del_transition(*e);
00129 }
00130 }
00131 m.insert(s2);
00132 }
00133 }
00134 return coaccessible(res);
00135 }
00136
00137
00141
00142 template <typename S, typename M1, typename M2, typename Auto_t>
00143 Auto_t
00144 do_insplitting(const AutomataBase<S>&,
00145 const algebra::FreeMonoidProduct<M1, M2>&,
00146 const Auto_t& aut,
00147 std::set<typename Auto_t::hstate_t>& m)
00148 {
00149 AUTOMATON_TYPES(Auto_t);
00150
00151 typedef typename series_set_elt_t::support_t support_t;
00152
00153 typedef typename monoid_t::first_monoid_t first_monoid_t;
00154
00155 typedef typename monoid_elt_value_t::first_type
00156 first_monoid_elt_value_t;
00157 typedef Element<first_monoid_t, first_monoid_elt_value_t>
00158 first_monoid_elt_t;
00159
00160 typedef std::list<htransition_t> set_of_transitions_t;
00161
00162
00163
00164 first_monoid_elt_t first_identity =
00165 algebra::identity_as<first_monoid_elt_value_t>::
00166 of(aut.structure().series().monoid().first_monoid());
00167
00168 Auto_t res(aut);
00169
00170 const series_set_t& series = res.structure().series();
00171 const monoid_t& monoid = series.monoid();
00172
00173
00174
00175 for_all_states(s, res)
00176 {
00177 bool eps_in = false;
00178 bool other_in = false;
00179 bool diff = false;
00180
00181
00182
00183 set_of_transitions_t transitions;
00184 res.rdeltac(transitions, *s, delta_kind::transitions());
00185 for_all_const_(set_of_transitions_t, e, transitions)
00186 {
00187 const series_set_elt_t series = res.series_of(*e);
00188 support_t supp = series.supp();
00189 const monoid_elt_t supp_elt (monoid, *(supp.begin()));
00190
00191 if (supp_elt.value().first == first_identity.value())
00192 eps_in = true;
00193 else
00194 other_in = true;
00195 if (eps_in and other_in)
00196 {
00197 diff = true;
00198 break;
00199 }
00200 }
00201
00202 if (eps_in and not diff)
00203 m.insert(*s);
00204
00205
00206 if (diff)
00207 {
00208 hstate_t s2 = res.add_state();
00209 if (res.is_final(*s))
00210 res.set_final(s2, res.get_final(*s));
00211
00212 set_of_transitions_t out_transitions;
00213 res.deltac(out_transitions, *s, delta_kind::transitions());
00214
00215 for_all_(set_of_transitions_t, e, out_transitions)
00216 res.add_series_transition(s2, res.dst_of(*e), res.series_of(*e));
00217
00218 for_all_const_(set_of_transitions_t, e, transitions)
00219 {
00220 const series_set_elt_t series = res.series_of(*e);
00221 support_t supp = series.supp();
00222 const monoid_elt_t supp_elt (monoid, *(supp.begin()));
00223
00224 if (supp_elt.value().first == first_identity.value())
00225 {
00226 res.add_series_transition(res.src_of(*e), s2,
00227 res.series_of(*e));
00228 res.del_transition(*e);
00229 }
00230 }
00231 m.insert(s2);
00232 }
00233 }
00234 return res;
00235 }
00236
00237
00238 template <typename S, typename T>
00239 Element<S, T>
00240 outsplitting(const Element<S, T>& aut,
00241 std::set<typename T::hstate_t>& states)
00242 {
00243 return do_outsplitting(aut.structure(),
00244 aut.structure().series().monoid(),
00245 aut,
00246 states);
00247 }
00248
00249
00250 template <typename S, typename T>
00251 Element<S, T>
00252 insplitting(const Element<S, T>& aut,
00253 std::set<typename T::hstate_t>& states)
00254 {
00255 return do_insplitting(aut.structure(),
00256 aut.structure().series().monoid(),
00257 aut,
00258 states);
00259 }
00260
00261
00262
00263 template <typename S, typename T>
00264 Element<S, T>
00265 outsplitting(const Element<S, T>& aut)
00266 {
00267 std::set<typename T::hstate_t> states;
00268 return do_outsplitting(aut.structure(),
00269 aut.structure().series().monoid(),
00270 aut,
00271 states);
00272 }
00273
00274
00275 template <typename S, typename T>
00276 Element<S, T>
00277 insplitting(const Element<S, T>& aut)
00278 {
00279 std::set<typename T::hstate_t> states;
00280 return do_insplitting(aut.structure(),
00281 aut.structure().series().monoid(),
00282 aut,
00283 states);
00284 }
00285 }
00286 }
00287
00288 #endif // ! VCSN_ALGORITHMS_OUTSPLITTING_HXX