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