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