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_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
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 }
00250
00251 #endif // ! VCSN_ALGORITHMS_SUB_NORMALIZE_HXX