00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_SUB_NORMALIZE_HXX
00018 # define VCSN_ALGORITHMS_SUB_NORMALIZE_HXX
00019
00029 namespace vcsn {
00030
00031
00032
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
00076
00077
00078 template <class Auto, class Label>
00079 int do_sub_normalize_initial_final(Auto& a,
00080 typename Auto::hstate_t s,
00081 const Label& label, bool initial)
00082 {
00083 BENCH_TASK_SCOPED("sub_normalize_transition");
00084 AUTOMATON_TYPES(Auto);
00085 hstate_t s0;
00086 hstate_t s1;
00087 typedef typename monoid_elt_t::first_monoid_elt_value_t
00088 first_monoid_elt_value_t;
00089 typedef typename monoid_elt_t::second_monoid_elt_value_t
00090 second_monoid_elt_value_t;
00091 typedef typename series_set_elt_t::support_t support_t;
00092
00093 monoid_elt_t m1(a.structure().series().monoid(),
00094 *(label.supp().begin()));
00095 first_monoid_elt_value_t w1 = m1.value().first;
00096 second_monoid_elt_value_t w2 = m1.value().second;
00097
00098 int size1 = w1.size();
00099 int size2 = w2.size();
00100
00101 unsigned int size = std::max(w1.size(), w2.size());
00102
00103 if(size>0 || label.supp().size()>1)
00104 {
00105 if(initial)
00106 {
00107 s0 = a.add_state();
00108 s1 = s;
00109 a.set_initial(s0);
00110 a.unset_initial(s);
00111 }
00112 else
00113 {
00114 s0 = s;
00115 s1 = a.add_state();
00116 a.set_final(s1);
00117 a.unset_final(s);
00118 }
00119 for_all_(support_t, supp, label.supp())
00120 {
00121 const monoid_elt_t supp_elt (a.structure().series().monoid(), *supp);
00122 const semiring_elt_t weight = label.get(supp_elt);
00123 series_set_elt_t in_series(a.structure().series());
00124 in_series.assoc(supp_elt, weight);
00125 a.add_series_transition(s0, s1, in_series);
00126 }
00127 }
00128 return 0;
00129 }
00130
00131 template <class Auto, class Label>
00132 int do_sub_normalize_transition(Auto& a,
00133 typename Auto::hstate_t start,
00134 typename Auto::hstate_t stop,
00135 const Label& label)
00136 {
00137 BENCH_TASK_SCOPED("sub_normalize_transition");
00138 AUTOMATON_TYPES(Auto);
00139 hstate_t s0;
00140 hstate_t s1;
00141 typedef typename monoid_elt_t::first_monoid_elt_t first_monoid_elt_t;
00142 typedef typename monoid_elt_t::second_monoid_elt_t
00143 second_monoid_elt_t;
00144 typedef typename monoid_elt_t::first_monoid_elt_value_t
00145 first_monoid_elt_value_t;
00146 typedef typename monoid_elt_t::second_monoid_elt_value_t
00147 second_monoid_elt_value_t;
00148
00149 first_monoid_elt_value_t m1_ident =
00150 algebra::identity_as<first_monoid_elt_value_t>
00151 ::of(a.structure().series().monoid().first_monoid()).value();
00152 second_monoid_elt_value_t m2_ident =
00153 algebra::identity_as<second_monoid_elt_value_t>
00154 ::of(a.structure().series().monoid().second_monoid()).value();
00155
00156 semiring_elt_t s_ident =
00157 algebra::identity_as<semiring_elt_value_t>
00158 ::of(a.structure().series().semiring());
00159
00160
00161 monoid_elt_t m1(a.structure().series().monoid(),
00162 *(label.supp().begin()));
00163 first_monoid_elt_value_t w1 = m1.value().first;
00164 second_monoid_elt_value_t w2 = m1.value().second;
00165
00166 int size1 = w1.size();
00167 int size2 = w2.size();
00168 int cpt1 = 0;
00169 int cpt2 = 0;
00170
00171 unsigned int size = std::max(w1.size(), w2.size());
00172
00173 if (size > 1)
00174 {
00175 monoid_elt_t m(a.structure().series().monoid());
00176
00177 semiring_elt_t s = label.get(m1);
00178 series_set_elt_t in_series(a.structure().series());
00179
00180 m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
00181 cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
00182
00183 in_series.assoc(m, s);
00184
00185 s0 = start;
00186 s1 = a.add_state();
00187 a.add_series_transition(s0, s1, in_series);
00188
00189 for (unsigned int i = 1; i < size - 1; ++i)
00190 {
00191 m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
00192 cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
00193 s0 = s1;
00194 s1 = a.add_state();
00195 series_set_elt_t series(a.structure().series());
00196 series.assoc(m, s_ident);
00197 a.add_series_transition(s0, s1, series);
00198 }
00199
00200 m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
00201 cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
00202
00203 series_set_elt_t out_series(a.structure().series());
00204 out_series.assoc(m, s_ident);
00205
00206 a.add_series_transition(s1, stop, out_series);
00207
00208 return 1;
00209 }
00210
00211 return 0;
00212 }
00213
00214
00215 template <class M1, class M2, class Auto, class Ret>
00216 void do_sub_normalize(const algebra::FreeMonoidProduct<M1, M2>&,
00217 const Auto& a,
00218 Ret& res)
00219 {
00220 BENCH_TASK_SCOPED("sub_normalize");
00221 AUTOMATON_TYPES(Ret);
00222 typedef std::vector<hstate_t> vector_t;
00223
00224 auto_copy(res, cut_up(a));
00225
00226 vector_t i_states; i_states.reserve(res.initial().size());
00227 vector_t f_states; f_states.reserve(res.final().size());
00228
00229 for_all_const_initial_states(f, res)
00230 i_states.push_back(*f);
00231 for_all_const_final_states(i, res)
00232 f_states.push_back(*i);
00233
00234 for_all_(vector_t, i, i_states)
00235 do_sub_normalize_initial_final(res, *i,
00236 res.get_initial(*i), true);
00237
00238 for_all_(vector_t, f, f_states)
00239 do_sub_normalize_initial_final(res, *f,
00240 res.get_final(*f), false);
00241
00242 transitions_t transitions = res.transitions();
00243
00244 for_all_(transitions_t, e, transitions)
00245 if (do_sub_normalize_transition(res, res.src_of(*e), res.dst_of(*e),
00246 res.series_of(*e)))
00247 res.del_transition(*e);
00248 }
00249
00250
00251
00252
00253
00254
00255 template <class S, class T>
00256 Element<S, T>
00257 sub_normalize(const Element<S, T>& a)
00258 {
00259 Element<S, T> res(a.structure());
00260 do_sub_normalize(a.structure().series().monoid(), a, res);
00261
00262 return res;
00263 }
00264
00265
00266 template <class S, class T>
00267 void
00268 sub_normalize(const Element<S, T>& a, Element<S, T>& res)
00269 {
00270 do_sub_normalize(a.structure().series().monoid(), a, res);
00271 }
00272
00273 template <class S, class T>
00274 void
00275 sub_normalize_here(Element<S, T>& a)
00276 {
00277 do_sub_normalize (a.structure().series().monoid(), a, a);
00278 }
00279
00280 template <class S, class T>
00281 bool is_sub_normalized(const Element<S, T>& a)
00282 {
00283 return do_is_sub_normalized(a.structure().series().monoid(), a);
00284 }
00285
00286 }
00287
00288 #endif // ! VCSN_ALGORITHMS_SUB_NORMALIZE_HXX