Vaucanson 1.4
|
00001 // sub_normalize.hxx: this file is part of the Vaucanson project. 00002 // 00003 // Vaucanson, a generic library for finite state machines. 00004 // 00005 // Copyright (C) 2005, 2006, 2008 The Vaucanson Group. 00006 // 00007 // This program is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU General Public License 00009 // as published by the Free Software Foundation; either version 2 00010 // of the License, or (at your option) any later version. 00011 // 00012 // The complete GNU General Public Licence Notice can be found as the 00013 // `COPYING' file in the root directory. 00014 // 00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file. 00016 // 00017 #ifndef VCSN_ALGORITHMS_SUB_NORMALIZE_HXX 00018 # define VCSN_ALGORITHMS_SUB_NORMALIZE_HXX 00019 00029 namespace vcsn { 00030 00031 /*------------------. 00032 | is_sub_normalized | 00033 `------------------*/ 00034 00035 template <class M1, class M2, class Auto> 00036 bool do_is_sub_normalized(const algebra::FreeMonoidProduct<M1, M2>&, 00037 const Auto& a) 00038 { 00039 BENCH_TASK_SCOPED("is_sub_normalized"); 00040 AUTOMATON_TYPES(Auto); 00041 typedef typename series_set_elt_t::support_t support_t; 00042 00043 for_all_const_initial_states(i, a) 00044 { 00045 series_set_elt_t label = a.get_initial(*i); 00046 for (typename support_t::const_iterator it = label.supp().begin(); 00047 it != label.supp().end(); ++it) 00048 if ((*it).first.size() > 1 || (*it).second.size() > 1) 00049 return false; 00050 } 00051 00052 for_all_const_final_states(f, a) 00053 { 00054 series_set_elt_t label = a.get_final(*f); 00055 for (typename support_t::const_iterator it = label.supp().begin(); 00056 it != label.supp().end(); ++it) 00057 if ((*it).first.size() > 1 || (*it).second.size() > 1) 00058 return false; 00059 } 00060 00061 for_all_const_transitions(e, a) 00062 { 00063 series_set_elt_t label = a.series_of(*e); 00064 for (typename support_t::const_iterator it = label.supp().begin(); 00065 it != label.supp().end(); ++it) 00066 if ((*it).first.size() > 1 || (*it).second.size() > 1) 00067 return false; 00068 } 00069 00070 return true; 00071 } 00072 00073 00074 /*--------------. 00075 | sub_normalize | 00076 `--------------*/ 00077 00078 template <class Auto, class Label> 00079 int do_sub_normalize_transition(Auto& a, 00080 typename Auto::hstate_t start, 00081 typename Auto::hstate_t stop, 00082 const Label& label, bool initial, bool final) 00083 { 00084 BENCH_TASK_SCOPED("sub_normalize_transition"); 00085 AUTOMATON_TYPES(Auto); 00086 hstate_t s0; 00087 hstate_t s1; 00088 typedef typename monoid_elt_t::first_monoid_elt_t first_monoid_elt_t; 00089 typedef typename monoid_elt_t::second_monoid_elt_t 00090 second_monoid_elt_t; 00091 typedef typename monoid_elt_t::first_monoid_elt_value_t 00092 first_monoid_elt_value_t; 00093 typedef typename monoid_elt_t::second_monoid_elt_value_t 00094 second_monoid_elt_value_t; 00095 00096 first_monoid_elt_value_t m1_ident = 00097 algebra::identity_as<first_monoid_elt_value_t> 00098 ::of(a.structure().series().monoid().first_monoid()).value(); 00099 second_monoid_elt_value_t m2_ident = 00100 algebra::identity_as<second_monoid_elt_value_t> 00101 ::of(a.structure().series().monoid().second_monoid()).value(); 00102 00103 semiring_elt_t s_ident = 00104 algebra::identity_as<semiring_elt_value_t> 00105 ::of(a.structure().series().semiring()); 00106 00107 00108 monoid_elt_t m1(a.structure().series().monoid(), 00109 *(label.supp().begin())); 00110 first_monoid_elt_value_t w1 = m1.value().first; 00111 second_monoid_elt_value_t w2 = m1.value().second; 00112 00113 int size1 = w1.size(); 00114 int size2 = w2.size(); 00115 int cpt1 = 0; 00116 int cpt2 = 0; 00117 00118 unsigned int size = std::max(w1.size(), w2.size()); 00119 00120 if (size > 1) 00121 { 00122 monoid_elt_t m(a.structure().series().monoid()); 00123 00124 semiring_elt_t s = label.get(m1); 00125 series_set_elt_t in_series(a.structure().series()); 00126 00127 m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident, 00128 cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident); 00129 00130 in_series.assoc(m, s); 00131 00132 if (initial) 00133 { 00134 s0 = a.add_state(); 00135 a.set_initial(s0, in_series); 00136 a.unset_initial(stop); 00137 s1 = s0; 00138 } 00139 else 00140 { 00141 s0 = start; 00142 s1 = a.add_state(); 00143 a.add_series_transition(s0, s1, in_series); 00144 } 00145 00146 for (unsigned int i = 1; i < size - 1; ++i) 00147 { 00148 m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident, 00149 cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident); 00150 s0 = s1; 00151 s1 = a.add_state(); 00152 series_set_elt_t series(a.structure().series()); 00153 series.assoc(m, s_ident); 00154 a.add_series_transition(s0, s1, series); 00155 } 00156 00157 m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident, 00158 cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident); 00159 00160 series_set_elt_t out_series(a.structure().series()); 00161 out_series.assoc(m, s_ident); 00162 00163 if (final) 00164 { 00165 a.unset_final(start); 00166 a.set_final(s1, out_series); 00167 } 00168 else 00169 a.add_series_transition(s1, stop, out_series); 00170 00171 return 1; 00172 } 00173 00174 return 0; 00175 } 00176 00177 00178 00179 template <class M1, class M2, class Auto, class Ret> 00180 void do_sub_normalize(const algebra::FreeMonoidProduct<M1, M2>&, 00181 const Auto& a, 00182 Ret& res) 00183 { 00184 BENCH_TASK_SCOPED("sub_normalize"); 00185 AUTOMATON_TYPES(Ret); 00186 typedef std::vector<hstate_t> vector_t; 00187 00188 auto_copy(res, cut_up(a)); 00189 00190 transitions_t transitions = res.transitions(); 00191 vector_t i_states; i_states.reserve(res.initial().size()); 00192 vector_t f_states; f_states.reserve(res.final().size()); 00193 00194 for_all_const_initial_states(f, res) 00195 i_states.push_back(*f); 00196 for_all_const_final_states(i, res) 00197 f_states.push_back(*i); 00198 00199 for_all_(vector_t, i, i_states) 00200 do_sub_normalize_transition(res, hstate_t(), *i, 00201 res.get_initial(*i), true, false); 00202 00203 for_all_(vector_t, f, f_states) 00204 do_sub_normalize_transition(res, *f, hstate_t(), 00205 res.get_final(*f), false, true); 00206 00207 for_all_(transitions_t, e, transitions) 00208 if (do_sub_normalize_transition(res, res.src_of(*e), res.dst_of(*e), 00209 res.series_of(*e), false, false)) 00210 res.del_transition(*e); 00211 } 00212 00213 00214 /*---------. 00215 | Wrappers | 00216 `---------*/ 00217 00218 template <class S, class T> 00219 Element<S, T> 00220 sub_normalize(const Element<S, T>& a) 00221 { 00222 Element<S, T> res(a.structure()); 00223 do_sub_normalize(a.structure().series().monoid(), a, res); 00224 00225 return res; 00226 } 00227 00228 00229 template <class S, class T> 00230 void 00231 sub_normalize(const Element<S, T>& a, Element<S, T>& res) 00232 { 00233 do_sub_normalize(a.structure().series().monoid(), a, res); 00234 } 00235 00236 template <class S, class T> 00237 void 00238 sub_normalize_here(Element<S, T>& a) 00239 { 00240 do_sub_normalize (a.structure().series().monoid(), a, a); 00241 } 00242 00243 template <class S, class T> 00244 bool is_sub_normalized(const Element<S, T>& a) 00245 { 00246 return do_is_sub_normalized(a.structure().series().monoid(), a); 00247 } 00248 00249 } // ! vcsn 00250 00251 #endif // ! VCSN_ALGORITHMS_SUB_NORMALIZE_HXX