Vaucanson 1.4
|
00001 // normalized.hxx: this file is part of the Vaucanson project. 00002 // 00003 // Vaucanson, a generic library for finite state machines. 00004 // 00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 The 00006 // Vaucanson Group. 00007 // 00008 // This program is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU General Public License 00010 // as published by the Free Software Foundation; either version 2 00011 // of the License, or (at your option) any later version. 00012 // 00013 // The complete GNU General Public Licence Notice can be found as the 00014 // `COPYING' file in the root directory. 00015 // 00016 // The Vaucanson Group consists of people listed in the `AUTHORS' file. 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/standard.hh> 00027 00028 # include <stack> 00029 00030 namespace vcsn { 00031 00032 /*-----------. 00033 | normalized | 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 | union_of_normalized | 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 union_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 | is_normalized | 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 // Check that there is no input transition on the initial state 00152 // and no output transition on the final state. 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 | concatenate_of_normalized | 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 | Concat of states | 00184 `-----------------*/ 00185 map_lhs_rhs_t map_h; 00186 00187 // If rhs initial multiplicity is 1 and so is lhs final multiplicity, 00188 // we can merge the lhs final state and the rhs initial state. 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 | Concat of transitions. | 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 // If initial multiplicity of rhs isn't 1, add a spontaneous transition 00221 // between lhs final state and rhs initial state, with lhs final 00222 // multiplicity * rhs initial multiplicity. 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 | star_of_normalized | 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 } // vcsn 00298 00299 #endif // ! VCSN_ALGORITHMS_NORMALIZED_HXX