18 #ifndef VCSN_ALGORITHMS_REDUCE_HXX
19 # define VCSN_ALGORITHMS_REDUCE_HXX
23 # include <vaucanson/misc/usual_macros.hh>
27 template<
typename A,
typename AI,
typename AO>
30 typedef Element<A, AI> Auto;
31 AUTOMATON_TYPES(Auto);
32 AUTOMATON_FREEMONOID_TYPES(Auto);
33 typedef std::vector<semiring_elt_t> semiring_vector_t;
34 typedef std::vector<std::map<std::size_t, semiring_elt_t> > semiring_matrix_t;
35 typedef std::map<monoid_elt_t, semiring_matrix_t> semiring_matrix_set_t;
43 reducer(
const Element<A, AI>& input, Element<A, AO>& output) :
44 zero(input.series().semiring().wzero_),
45 one(input.series().semiring().wone_),
46 empty_word(input.series().monoid().VCSN_EMPTY_),
49 std::map<hstate_t, int> state_to_index;
52 for_all_const_states(s, input)
53 state_to_index[*s] = i++;
63 for_all_const_initial_states(s, input)
64 init[state_to_index[*s]] = input.get_initial(*s).
get(empty_word);
66 for_all_const_final_states(s, input)
67 final[state_to_index[*s]] = input.get_final(*s).
get(empty_word);
69 for_all_const_transitions(t, input)
71 series_set_elt_t s = input.series_of(*t);
73 for_all_(series_set_elt_t::support_t, l, s.supp())
75 const monoid_elt_t m(input.structure().series().monoid(), *l);
76 typename semiring_matrix_set_t::iterator it = letter_matrix_set.find(m);
77 if (it == letter_matrix_set.end())
78 it = letter_matrix_set.insert(make_pair(m, semiring_matrix_t(nb_states))).first;
79 it->second[state_to_index[input.src_of(*t)]][state_to_index[input.dst_of(*t)]] = s.get(m);
88 semiring_vector_t vector;
91 triple_t(
const hstate_t& state,
const semiring_vector_t& vector,
92 const monoid_elt_t& letter) :
93 state(state), vector(vector), letter(letter) {}
98 void product_vector_matrix(
const semiring_vector_t& v,
99 const semiring_matrix_t& m,
100 semiring_vector_t& res)
102 for(
int i=0; i<nb_states; i++)
103 for(
typename std::map<std::size_t, semiring_elt_t>::const_iterator it
104 = m[i].begin(); it != m[i].end(); ++it)
107 res[j] += v[i] * it->second;
111 semiring_elt_t scalar_product(
const semiring_vector_t& v,
112 const semiring_vector_t& w)
114 semiring_elt_t res(zero);
115 for(
int i = 0; i < nb_states; ++i)
127 for (i = 0; i < nb_states; ++i)
134 std::queue<triple_t> queue;
137 std::list<std::pair<hstate_t,semiring_vector_t> > base;
140 hstate_t n_init = output.add_state();
141 base.push_back(std::pair<hstate_t,semiring_vector_t>(n_init, init));
142 output.set_initial(n_init);
144 semiring_elt_t t = scalar_product(init,
final);
147 series_set_elt_t s(output.structure().series());
148 s.assoc(empty_word, t);
149 output.set_final(n_init, s);
155 for (
typename semiring_matrix_set_t::const_iterator it
156 = letter_matrix_set.begin(); it != letter_matrix_set.end(); ++it)
158 semiring_vector_t nv(nb_states);
159 product_vector_matrix(init, it->second, nv);
160 queue.push(triple_t(n_init, nv, it->first));
162 while (!queue.empty())
164 triple_t& tr = queue.front();
166 semiring_vector_t& current = tr.vector;
168 std::size_t curr_fnn = 0;
169 std::size_t base_fnn = 0;
170 for(
typename std::list<std::pair<hstate_t,semiring_vector_t> >::iterator it
171 = base.begin(); it!=base.end(); ++it)
173 while (curr_fnn < nb_states && current[curr_fnn] == zero)
177 semiring_vector_t& vbase = it->second;
178 while (base_fnn < nb_states && vbase[base_fnn] == zero)
181 if (base_fnn < curr_fnn)
185 if (base_fnn > curr_fnn)
188 hstate_t n_state= output.add_state();
189 base.insert(it,std::pair<hstate_t,semiring_vector_t>(n_state,
191 series_set_elt_t s(output.structure().series());
192 s.assoc(tr.letter, one);
193 output.add_series_transition(tr.state, n_state, s);
194 semiring_elt_t t=scalar_product(current,
final);
197 series_set_elt_t s(output.structure().series());
198 s.assoc(empty_word, t);
199 output.set_final(n_state, s);
202 for (
typename semiring_matrix_set_t::const_iterator itm
203 = letter_matrix_set.begin();
204 itm != letter_matrix_set.end(); ++itm)
206 semiring_vector_t nv(nb_states);
207 product_vector_matrix(current, itm->second, nv);
208 queue.push(triple_t(n_state, nv, itm->first));
211 curr_fnn = nb_states;
216 semiring_elt_t ratio = current[curr_fnn] / vbase[curr_fnn];
218 current[curr_fnn] = zero;
219 for(
int i = curr_fnn+1; i < nb_states; ++i)
220 current[i ] =current[i] - ratio*vbase[i];
221 series_set_elt_t s(output.structure().series());
222 s.assoc(tr.letter, ratio);
223 output.add_series_transition(tr.state, it->first, s);
227 while (curr_fnn < nb_states && current[curr_fnn] == zero)
229 if (nb_states> curr_fnn)
232 hstate_t n_state= output.add_state();
233 base.push_back(std::pair<hstate_t,semiring_vector_t>(n_state,
235 series_set_elt_t s(output.structure().series());
236 s.assoc(tr.letter, one);
237 output.add_series_transition(tr.state, n_state, s);
238 semiring_elt_t t=scalar_product(current,
final);
241 series_set_elt_t s(output.structure().series());
242 s.assoc(empty_word, t);
243 output.set_final(n_state, s);
245 for (
typename semiring_matrix_set_t::const_iterator itm
246 = letter_matrix_set.begin();
247 itm != letter_matrix_set.end(); ++itm)
249 semiring_vector_t nv(nb_states);
250 product_vector_matrix(current, itm->second, nv);
251 queue.push(triple_t(n_state, nv, itm->first));
271 monoid_elt_t empty_word;
274 semiring_vector_t init;
275 semiring_vector_t
final;
276 semiring_matrix_set_t letter_matrix_set;
279 Element<A, AO>& output;
282 template<
typename A,
typename AI,
typename AO>
284 do_semi_reduce(
const Element<A, AI>& a, Element<A, AO>& output)
286 reducer<A, AI, AO> r(a, output);
290 template<
typename A,
typename AI>
296 do_semi_reduce(a, output);
300 template<
typename A,
typename AI>
307 if (dir == misc::right_left)
315 do_semi_reduce(a, tmp);
324 #endif // !VCSN_ALGORITHMS_REDUCE_HXX //