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 TIMER_SCOPED("is_sub_normalized");
00040 AUTOMATON_TYPES(Auto);
00041 typedef typename series_set_elt_t::support_t support_t;
00042
00043 for_all_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_final_states(f, a)
00053 {
00054 series_set_elt_t label = a.get_initial(*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_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 hstate_t start, hstate_t stop,
00081 const Label& label, bool initial, bool final)
00082 {
00083 TIMER_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_t first_monoid_elt_t;
00088 typedef typename monoid_elt_t::second_monoid_elt_t
00089 second_monoid_elt_t;
00090 typedef typename monoid_elt_t::first_monoid_elt_value_t
00091 first_monoid_elt_value_t;
00092 typedef typename monoid_elt_t::second_monoid_elt_value_t
00093 second_monoid_elt_value_t;
00094
00095 first_monoid_elt_value_t m1_ident =
00096 algebra::identity_as<first_monoid_elt_value_t>
00097 ::of(a.structure().series().monoid().first_monoid()).value();
00098 second_monoid_elt_value_t m2_ident =
00099 algebra::identity_as<second_monoid_elt_value_t>
00100 ::of(a.structure().series().monoid().second_monoid()).value();
00101
00102 semiring_elt_t s_ident =
00103 algebra::identity_as<semiring_elt_value_t>
00104 ::of(a.structure().series().semiring());
00105
00106
00107 monoid_elt_t m1(a.structure().series().monoid(),
00108 *(label.supp().begin()));
00109 first_monoid_elt_value_t w1 = m1.value().first;
00110 second_monoid_elt_value_t w2 = m1.value().second;
00111
00112 int size1 = w1.size();
00113 int size2 = w2.size();
00114 int cpt1 = 0;
00115 int cpt2 = 0;
00116
00117 unsigned int size = std::max(w1.size(), w2.size());
00118
00119 if (size > 1)
00120 {
00121 monoid_elt_t m(a.structure().series().monoid());
00122
00123 semiring_elt_t s = label.get(m1);
00124 series_set_elt_t in_series(a.structure().series());
00125
00126 m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
00127 cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
00128
00129 in_series.assoc(m, s);
00130
00131 if (initial)
00132 {
00133 s0 = a.add_state();
00134 a.set_initial(s0, in_series);
00135 a.unset_initial(stop);
00136 s1 = s0;
00137 }
00138 else
00139 {
00140 s0 = start;
00141 s1 = a.add_state();
00142 a.add_series_transition(s0, s1, in_series);
00143 }
00144
00145 for (unsigned int i = 1; i < size - 1; ++i)
00146 {
00147 m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
00148 cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
00149 s0 = s1;
00150 s1 = a.add_state();
00151 series_set_elt_t series(a.structure().series());
00152 series.assoc(m, s_ident);
00153 a.add_series_transition(s0, s1, series);
00154 }
00155
00156 m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
00157 cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
00158
00159 series_set_elt_t out_series(a.structure().series());
00160 out_series.assoc(m, s_ident);
00161
00162 if (final)
00163 {
00164 a.unset_final(start);
00165 a.set_final(s1, out_series);
00166 }
00167 else
00168 a.add_series_transition(s1, stop, out_series);
00169
00170 return 1;
00171 }
00172
00173 return 0;
00174 }
00175
00176
00177
00178 template <class M1, class M2, class Auto, class Ret>
00179 void do_sub_normalize(const algebra::FreeMonoidProduct<M1, M2>&,
00180 const Auto& a,
00181 Ret& res)
00182 {
00183 TIMER_SCOPED("sub_normalize");
00184 AUTOMATON_TYPES(Ret);
00185 typedef std::vector<hstate_t> vector_t;
00186
00187 auto_copy(res, cut_up(a));
00188
00189 transitions_t transitions = res.transitions();
00190 vector_t i_states; i_states.reserve(res.initial().size());
00191 vector_t f_states; f_states.reserve(res.final().size());
00192
00193 for_all_initial_states(f, res)
00194 i_states.push_back(*f);
00195 for_all_final_states(i, res)
00196 f_states.push_back(*i);
00197
00198 for_all_(vector_t, i, i_states)
00199 do_sub_normalize_transition(res, hstate_t(), *i,
00200 res.get_initial(*i), true, false);
00201
00202 for_all_(vector_t, f, f_states)
00203 do_sub_normalize_transition(res, *f, hstate_t(),
00204 res.get_final(*f), false, true);
00205
00206 for_all_(transitions_t, e, transitions)
00207 if (do_sub_normalize_transition(res, res.src_of(*e), res.dst_of(*e),
00208 res.series_of(*e), false, false))
00209 res.del_transition(*e);
00210 }
00211
00212
00213
00214
00215
00216
00217 template <class S, class T>
00218 Element<S, T>
00219 sub_normalize(const Element<S, T>& a)
00220 {
00221 Element<S, T> res(a.structure());
00222 do_sub_normalize(a.structure().series().monoid(), a, res);
00223
00224 return res;
00225 }
00226
00227
00228 template <class S, class T>
00229 void
00230 sub_normalize(const Element<S, T>& a, Element<S, T>& res)
00231 {
00232 do_sub_normalize(a.structure().series().monoid(), a, res);
00233 }
00234
00235 template <class S, class T>
00236 void
00237 sub_normalize_here(Element<S, T>& a)
00238 {
00239 do_sub_normalize (a.structure().series().monoid(), a, a);
00240 }
00241
00242 template <class S, class T>
00243 bool is_sub_normalized(const Element<S, T>& a)
00244 {
00245 return do_is_sub_normalized(a.structure().series().monoid(), a);
00246 }
00247
00248 }
00249
00250 #endif // ! VCSN_ALGORITHMS_SUB_NORMALIZE_HXX