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