00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef VCSN_ALGORITHMS_STANDARD_HXX
00019 # define VCSN_ALGORITHMS_STANDARD_HXX
00020
00021 # include <vaucanson/algorithms/standard.hh>
00022 # include <vaucanson/algorithms/internal/has_neighbour.hh>
00023
00024 # include <vaucanson/algorithms/sum.hh>
00025 # include <vaucanson/algorithms/accessible.hh>
00026 # include <vaucanson/automata/concept/automata_base.hh>
00027 # include <vaucanson/misc/usual_macros.hh>
00028
00029 # include <set>
00030
00031 namespace vcsn {
00032
00033
00034
00035
00036 template <class A, typename AI>
00037 void
00038 do_in_standardize(const AutomataBase<A>&, Element<A, AI>& a)
00039 {
00040 TIMER_SCOPED("standardize");
00041 typedef Element<A, AI> automaton_t;
00042 AUTOMATON_TYPES(automaton_t);
00043
00044 hstate_t i = a.add_state();
00045 std::list<htransition_t> transition_oi;
00046 series_set_elt_t final_series =
00047 algebra::zero_as<series_set_elt_value_t>::of(a.series());
00048
00049 for_all_const_initial_states(oi, a)
00050 {
00051 series_set_elt_t s = a.get_initial(*oi);
00052
00053
00054 transition_oi.clear();
00055 a.deltac(transition_oi, *oi, delta_kind::transitions());
00056 for_all_const_(std::list<htransition_t>, oil, transition_oi)
00057 {
00058 series_set_elt_t t = s * a.series_of(*oil);
00059 a.add_series_transition(i, a.dst_of(*oil), t);
00060 }
00061
00062 final_series += s * a.get_final(*oi);
00063 }
00064
00065
00066
00067
00068
00069 for (initial_iterator oi = a.initial().begin(), next = oi;
00070 oi != a.initial().end();
00071 oi = next)
00072 {
00073 ++next;
00074 if (!has_predecessors(a, *oi))
00075 a.del_state(*oi);
00076 }
00077 a.clear_initial();
00078 a.set_initial(i);
00079 a.set_final(i, final_series);
00080 }
00081
00082 template<typename A, typename AI>
00083 void
00084 standardize(Element<A, AI>& a)
00085 {
00086 do_in_standardize(a.structure(), a);
00087 }
00088
00089
00090
00091
00092
00093 template <typename A, typename AI1, typename AI2>
00094 void
00095 do_union_of_standard_here(const AutomataBase<A>&,
00096 Element<A, AI1>& lhs,
00097 const Element<A, AI2>& rhs)
00098 {
00099 precondition(is_standard(lhs));
00100 precondition(is_standard(rhs));
00101
00102 TIMER_SCOPED("union_of_standard");
00103 typedef Element<A, AI1> lhs_t;
00104 typedef Element<A, AI2> rhs_t;
00105 typedef std::list<typename lhs_t::htransition_t> edelta_ret_t;
00106
00107
00108 typename lhs_t::hstate_t new_i = *lhs.initial().begin();
00109 sum_here(lhs, rhs);
00110
00111
00112
00113 typename lhs_t::initial_support_t initial = lhs.initial();
00114
00115
00116 assertion (initial.size() == 2);
00117 typename lhs_t::initial_iterator i = initial.begin();
00118 typename lhs_t::hstate_t old_i = *i != new_i ? *i : *++i;
00119
00120 lhs.set_final(new_i,
00121 lhs.get_final(new_i) + lhs.get_final(old_i));
00122
00123
00124 edelta_ret_t dst;
00125 lhs.deltac(dst, old_i, delta_kind::transitions());
00126 for_all_const_(edelta_ret_t, d, dst)
00127 {
00128 lhs.add_transition(new_i,
00129 lhs.dst_of(*d),
00130 lhs.label_of(*d));
00131 lhs.del_transition(*d);
00132 }
00133 lhs.del_state(old_i);
00134 }
00135
00136 template<typename A, typename AI1, typename AI2>
00137 void
00138 union_of_standard_here(Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00139 {
00140 do_union_of_standard_here(lhs.structure(), lhs, rhs);
00141 }
00142
00143 template<typename A, typename AI1, typename AI2>
00144 Element<A, AI1>
00145 union_of_standard(const Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00146 {
00147 Element<A, AI1> ret(lhs);
00148 union_of_standard_here(ret, rhs);
00149 return ret;
00150 }
00151
00152
00153
00154
00155 template <typename A, typename AI>
00156 bool
00157 do_is_standard(const AutomataBase<A>&, const Element<A, AI>& a)
00158 {
00159 TIMER_SCOPED("is_standard");
00160 typedef Element<A, AI> automaton_t;
00161 typedef typename automaton_t::series_set_elt_value_t series_set_elt_value_t;
00162
00163
00164 if (a.initial().size() != 1)
00165 return false;
00166
00167
00168 typename automaton_t::hstate_t s = *a.initial().begin();
00169 if (a.get_initial(s)
00170 != a.series().identity(SELECT(series_set_elt_value_t)))
00171 return false;
00172
00173
00174 return !has_predecessors(a, s);
00175 }
00176
00177 template<typename A, typename AI>
00178 bool
00179 is_standard(const Element<A, AI>& a)
00180 {
00181 return do_is_standard(a.structure(), a);
00182 }
00183
00184
00185
00186
00187 template <typename A, typename AI1, typename AI2>
00188 void
00189 do_concat_of_standard_here(const AutomataBase<A>&,
00190 Element<A, AI1>& lhs,
00191 const Element<A, AI2>& rhs)
00192 {
00193 precondition(is_standard(lhs));
00194 precondition(is_standard(rhs));
00195
00196 TIMER_SCOPED("concat_of_standard");
00197 typedef Element<A, AI1> lhs_t;
00198 typedef Element<A, AI2> rhs_t;
00199 AUTOMATON_TYPES(lhs_t);
00200 typedef std::map<hstate_t, hstate_t> map_t;
00201 typedef std::list<htransition_t> delta_ret_t;
00202
00203
00204
00205
00206 map_t map_h;
00207 delta_ret_t dst;
00208 hstate_t new_state;
00209
00210
00211 for (typename rhs_t::state_iterator s = rhs.states().begin();
00212 s != rhs.states().end();
00213 ++s)
00214 if (!rhs.is_initial(*s))
00215 {
00216 new_state = lhs.add_state();
00217 map_h[*s] = new_state;
00218 }
00219
00220
00221 for (typename rhs_t::state_iterator i = rhs.states().begin();
00222 i != rhs.states().end();
00223 ++i)
00224 if (!rhs.is_initial(*i))
00225 {
00226 dst.clear();
00227 rhs.deltac(dst, *i, delta_kind::transitions());
00228 for_all_const_(delta_ret_t, d, dst)
00229 lhs.add_transition(map_h[*i],
00230 map_h[rhs.dst_of(*d)],
00231 rhs.label_of(*d));
00232 }
00233
00234
00235 hstate_t rhs_i = *rhs.initial().begin();
00236 dst.clear();
00237 rhs.deltac(dst, rhs_i, delta_kind::transitions());
00238 for_all_const_final_states(f, lhs)
00239 {
00240 typename lhs_t::series_set_elt_t weight = lhs.get_final(*f);
00241 for_all_const_(delta_ret_t, d, dst)
00242 lhs.add_series_transition(*f,
00243 map_h[rhs.dst_of(*d)],
00244 weight * rhs.label_of(*d));
00245 }
00246
00247
00248
00249 typename lhs_t::series_set_elt_t rhs_iw = rhs.get_final(rhs_i);
00250 typename lhs_t::final_support_t support = lhs.final();
00251 for (typename lhs_t::final_iterator next = lhs.final().begin();
00252 next != lhs.final().end();)
00253 {
00254 typename lhs_t::final_iterator f = next;
00255 next++;
00256 lhs.set_final(*f, lhs.get_final(*f) * rhs_iw);
00257 }
00258
00259
00260 for_all_const_(map_t, nf, map_h)
00261 if (rhs.is_final(nf->first))
00262 lhs.set_final(nf->second, rhs.get_final(nf->first));
00263 }
00264
00265 template<typename A, typename AI1, typename AI2>
00266 void
00267 concat_of_standard_here(Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00268 {
00269 do_concat_of_standard_here(lhs.structure(), lhs, rhs);
00270 }
00271
00272 template<typename A, typename AI1, typename AI2>
00273 Element<A, AI1>
00274 concat_of_standard(const Element<A, AI1>& lhs,
00275 const Element<A, AI2>& rhs)
00276 {
00277 Element<A, AI1> ret(lhs);
00278 do_concat_of_standard_here(ret.structure(), ret, rhs);
00279 return ret;
00280 }
00281
00282
00283
00284
00285 template <typename A, typename AI>
00286 void
00287 do_star_of_standard_here(const AutomataBase<A>&, Element<A, AI>& a)
00288 {
00289 precondition(is_standard(a));
00290
00291 TIMER_SCOPED("star_of_standard");
00292 typedef Element<A, AI> automaton_t;
00293 AUTOMATON_TYPES(automaton_t);
00294 typedef std::list<htransition_t> edelta_ret_t;
00295
00296 edelta_ret_t dst;
00297 hstate_t new_i = *a.initial().begin();
00298 series_set_elt_t out_mult = a.get_final(new_i);
00299
00300 out_mult.star();
00301 a.deltac(dst, new_i, delta_kind::transitions());
00302 for_all_final_states(f, a)
00303 {
00304 if (*f != new_i)
00305 {
00306 series_set_elt_t f_mult = a.get_final(*f) * out_mult;
00307 a.set_final(*f, f_mult);
00308 for_all_const_(edelta_ret_t, d, dst)
00309 a.add_series_transition(*f, a.dst_of(*d), f_mult * a.label_of(*d));
00310 }
00311 }
00312 a.set_final(new_i, out_mult);
00313 }
00314
00315 template<typename A, typename AI>
00316 void
00317 star_of_standard_here(Element<A, AI>& a)
00318 {
00319 do_star_of_standard_here(a.structure(), a);
00320 }
00321
00322 template<typename A, typename AI>
00323 Element<A, AI>
00324 star_of_standard(const Element<A, AI>& a)
00325 {
00326 Element<A, AI> ret(a);
00327 do_star_of_standard_here(ret.structure(), ret);
00328 return ret;
00329 }
00330
00331 }
00332
00333 #endif // ! VCSN_ALGORITHMS_STANDARD_HXX