00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef VCSN_ALGORITHMS_NORMALIZED_HXX
00019 # define VCSN_ALGORITHMS_NORMALIZED_HXX
00020
00021 # include <vaucanson/algorithms/normalized.hh>
00022 # include <vaucanson/algorithms/internal/has_neighbour.hh>
00023
00024 # include <vaucanson/automata/concept/automata_base.hh>
00025 # include <vaucanson/misc/usual_macros.hh>
00026 # include <vaucanson/algorithms/sum.hh>
00027
00028 # include <stack>
00029
00030 namespace vcsn {
00031
00032
00033
00034
00035 template <typename A, typename AI>
00036 void
00037 do_normalize_here(const AutomataBase<A>&,
00038 Element<A, AI>& a)
00039 {
00040 BENCH_TASK_SCOPED("normalize");
00041 typedef Element<A, AI> automaton_t;
00042 AUTOMATON_TYPES(automaton_t);
00043
00044 hstate_t h = a.add_state();
00045
00046 for_all_const_initial_states(i, a)
00047 a.add_series_transition(h, *i, a.get_initial(*i));
00048
00049 a.clear_initial();
00050 a.set_initial(h);
00051
00052 h = a.add_state();
00053
00054 for_all_const_final_states(i, a)
00055 a.add_series_transition(*i, h, a.get_final(*i));
00056
00057 a.clear_final();
00058 a.set_final(h);
00059 }
00060
00061 template <typename A, typename AI>
00062 Element<A, AI>
00063 normalize(const Element<A, AI>& a)
00064 {
00065 Element<A, AI> result(a);
00066 do_normalize_here(result.structure(), result);
00067 return result;
00068 }
00069
00070 template<typename A, typename AI>
00071 void
00072 normalize_here(Element<A, AI>& a)
00073 {
00074 do_normalize_here(a.structure(), a);
00075 }
00076
00077
00078
00079
00080
00081
00082 template <typename A, typename AI1, typename AI2>
00083 void
00084 do_union_of_normalized_here(const AutomataBase<A>&,
00085 Element<A, AI1>& lhs,
00086 const Element<A, AI2>& rhs)
00087 {
00088 BENCH_TASK_SCOPED("union_of_normalized");
00089 typedef Element<A, AI1> lhs_t;
00090 typedef Element<A, AI2> rhs_t;
00091 AUTOMATON_TYPES(lhs_t);
00092 monoid_elt_t monoid_identity =
00093 lhs.series().monoid().identity(SELECT(monoid_elt_value_t));
00094 hstate_t new_i = lhs.add_state();
00095 hstate_t new_f = lhs.add_state();
00096
00097 sum_here(lhs, rhs);
00098
00099 for_all_const_initial_states(i, lhs)
00100 lhs.add_spontaneous(new_i, *i, lhs.get_initial(*i).get(monoid_identity));
00101 lhs.clear_initial();
00102
00103 for_all_const_final_states(f, lhs)
00104 lhs.add_spontaneous(*f, new_f, lhs.get_final(*f).get(monoid_identity));
00105 lhs.clear_final();
00106
00107 lhs.set_final(new_f);
00108 lhs.set_initial(new_i);
00109 }
00110
00111 template<typename A, typename AI1, typename AI2>
00112 void
00113 union_of_normalized_here(Element<A, AI1>& lhs,
00114 const Element<A, AI2>& rhs)
00115 {
00116 do_union_of_normalized_here(lhs.structure(), lhs, rhs);
00117 }
00118
00119 template<typename A, typename AI1, typename AI2>
00120 Element<A, AI1>
00121 union_of_normalized(const Element<A, AI1>& lhs,
00122 const Element<A, AI2>& rhs)
00123 {
00124 Element<A, AI1> ret(lhs);
00125 do_union_of_normalized_here(ret.structure(), ret, rhs);
00126 return ret;
00127 }
00128
00129
00130
00131
00132 template <typename A, typename AI>
00133 bool
00134 do_is_normalized(const AutomataBase<A>&,
00135 const Element<A, AI>& a)
00136 {
00137 BENCH_TASK_SCOPED("is_normalized");
00138 typedef Element<A, AI> automaton_t;
00139 typedef typename automaton_t::series_set_elt_value_t series_set_elt_value_t;
00140 typedef typename automaton_t::series_set_elt_t series_set_elt_t;
00141
00142 series_set_elt_t series_identity =
00143 a.series().identity(SELECT(series_set_elt_value_t));
00144
00145 if (a.initial().size() != 1
00146 || a.final().size() != 1
00147 || a.get_initial(*a.initial().begin()) != series_identity
00148 || a.get_final(*a.final().begin()) != series_identity)
00149 return false;
00150
00151
00152
00153 return !has_successors(a, *a.final().begin())
00154 && !has_predecessors(a, *a.initial().begin());
00155 }
00156
00157 template<typename A, typename AI>
00158 bool
00159 is_normalized(const Element<A, AI>& a)
00160 {
00161 return do_is_normalized(a.structure(), a);
00162 }
00163
00164
00165
00166
00167 template <typename A, typename AI1, typename AI2>
00168 void
00169 do_concatenate_of_normalized_here(const AutomataBase<A>&,
00170 Element<A, AI1>& lhs,
00171 const Element<A, AI2>& rhs)
00172 {
00173 BENCH_TASK_SCOPED("concatenate_of_normalized");
00174 typedef Element<A, AI1> lhs_t;
00175 typedef Element<A, AI2> rhs_t;
00176 AUTOMATON_TYPES(rhs_t);
00177 typedef std::map<hstate_t, hstate_t> map_lhs_rhs_t;
00178 typedef std::list<htransition_t> delta_ret_t;
00179
00180 hstate_t glue_state = *lhs.final().begin();
00181
00182
00183
00184
00185 map_lhs_rhs_t map_h;
00186
00187
00188
00189 bool merge_lhs_final_and_rhs_initial =
00190 (lhs.get_final(*lhs.final().begin()).value() ==
00191 lhs.series().identity(SELECT(series_set_elt_value_t)) &&
00192 rhs.get_initial(*rhs.initial().begin()).value() ==
00193 rhs.series().identity(SELECT(series_set_elt_value_t)));
00194
00195 for_all_const_states(s, rhs)
00196 {
00197 hstate_t new_state;
00198
00199 if (merge_lhs_final_and_rhs_initial)
00200 {
00201 if (rhs.is_initial(*s))
00202 new_state = glue_state;
00203 else
00204 new_state = lhs.add_state();
00205 }
00206 else
00207 new_state = lhs.add_state();
00208 map_h[*s] = new_state;
00209 lhs.set_final(new_state, rhs.get_final(*s));
00210 }
00211
00212
00213
00214
00215 for_all_const_transitions(t, rhs)
00216 lhs.add_transition(map_h[rhs.src_of(*t)],
00217 map_h[rhs.dst_of(*t)],
00218 rhs.label_of(*t));
00219
00220
00221
00222
00223 if (!merge_lhs_final_and_rhs_initial)
00224 {
00225 monoid_elt_t monoid_identity =
00226 rhs.series().monoid().identity(SELECT(monoid_elt_value_t));
00227 hstate_t i = *rhs.initial().begin();
00228 hstate_t f = *lhs.final().begin();
00229
00230 lhs.add_spontaneous(f, map_h[i],
00231 lhs.get_final(f).get(monoid_identity) *
00232 rhs.get_initial(i).get(monoid_identity));
00233 lhs.unset_final(f);
00234 lhs.unset_initial(map_h[i]);
00235 }
00236 }
00237
00238 template<typename A, typename AI1, typename AI2>
00239 void
00240 concatenate_of_normalized_here(Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00241 {
00242 do_concatenate_of_normalized_here(lhs.structure(), lhs, rhs);
00243 }
00244
00245 template<typename A, typename AI1, typename AI2>
00246 Element<A, AI1>
00247 concatenate_of_normalized(const Element<A, AI1>& lhs, const Element<A, AI2>& rhs)
00248 {
00249 Element<A, AI1> ret(lhs);
00250 do_concatenate_of_normalized_here(ret.structure(), ret, rhs);
00251 return ret;
00252 }
00253
00254
00255
00256
00257 template <typename A, typename AI>
00258 void
00259 do_star_of_normalized_here(const AutomataBase<A>&, Element<A, AI>& a)
00260 {
00261 BENCH_TASK_SCOPED("star_of_normalized");
00262 typedef Element<A, AI> automaton_t;
00263 AUTOMATON_TYPES(automaton_t);
00264 monoid_elt_t monoid_identity =
00265 a.series().monoid().identity(SELECT(monoid_elt_value_t));
00266 hstate_t old_i = *a.initial().begin();
00267 hstate_t old_f = *a.final().begin();
00268 hstate_t new_i = a.add_state();
00269 hstate_t new_f = a.add_state();
00270
00271 a.add_spontaneous(old_f, old_i, a.get_initial(old_i).get(monoid_identity));
00272 a.add_spontaneous(new_i, old_i, a.get_initial(old_i).get(monoid_identity));
00273 a.add_spontaneous(old_f, new_f, a.get_final(old_f).get(monoid_identity));
00274 a.add_spontaneous(new_i, new_f);
00275 a.set_final(new_f);
00276 a.unset_final(old_f);
00277 a.set_initial(new_i);
00278 a.unset_initial(old_i);
00279 }
00280
00281 template<typename A, typename AI>
00282 void
00283 star_of_normalized_here(Element<A, AI>& a)
00284 {
00285 do_star_of_normalized_here(a.structure(), a);
00286 }
00287
00288 template<typename A, typename AI>
00289 Element<A, AI>
00290 star_of_normalized(const Element<A, AI>& a)
00291 {
00292 Element<A, AI> ret(a);
00293 do_star_of_normalized_here(ret.structure(), ret);
00294 return ret;
00295 }
00296
00297 }
00298
00299 #endif // ! VCSN_ALGORITHMS_NORMALIZED_HXX