00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_EPS_REMOVAL_HXX
00018 # define VCSN_ALGORITHMS_EPS_REMOVAL_HXX
00019
00020 # include <vaucanson/algorithms/eps_removal.hh>
00021
00022 # include <vaucanson/automata/concept/automata_base.hh>
00023 # include <vaucanson/misc/usual_macros.hh>
00024
00025 # include <vector>
00026 # include <queue>
00027 # include <map>
00028 # include <utility>
00029
00030 namespace vcsn {
00031
00032
00033
00034
00035
00036 template
00037 <class A_, typename Auto, typename Weight>
00038 class EpsilonRemover
00039 {
00040 AUTOMATON_TYPES(Auto);
00041 typedef std::vector<std::vector<semiring_elt_t> > matrix_semiring_elt_t;
00042 typedef std::vector<series_set_elt_t> vector_series_t;
00043
00044 public:
00045 EpsilonRemover(const AutomataBase<A_>&,
00046 Auto& aut)
00047 : a(aut),
00048 size(aut.states().size()),
00049 null_series(aut.series().zero_),
00050 semiring_elt_zero(aut.series().semiring().wzero_),
00051 monoid_identity(aut.series().monoid().VCSN_EMPTY_)
00052 {
00053
00055
00056 index_to_state.resize(size);
00057 int i = 0;
00058 for_all_const_states(s, a)
00059 {
00060 index_to_state[i] = *s;
00061 state_to_index[*s] = i++;
00062 }
00063
00064
00065
00066 m_semiring_elt.resize(size);
00067 for (int i = 0; i < size; i++)
00068 m_semiring_elt[i].resize(size, semiring_elt_zero);
00069
00070 for_all_const_states(s, a)
00071 {
00072 std::list<htransition_t> transition_list;
00073 int src = state_to_index[*s];
00074
00075 for (delta_iterator e(a.value(), *s); ! e.done(); e.next())
00076 transition_list.push_back(*e);
00077 for_all_const_(std::list<htransition_t>, e, transition_list)
00078 {
00079 int dst = state_to_index[a.dst_of(*e)];
00080 series_set_elt_t t = a.series_of(*e);
00081
00082 m_semiring_elt[src][dst] += t.get(monoid_identity);
00083 t.assoc(monoid_identity.value(), semiring_elt_zero.value());
00084 if (t != null_series)
00085 a.add_series_transition(*s, a.dst_of(*e), t);
00086 a.del_transition(*e);
00087 }
00088 }
00089 }
00090
00091 void operator() (misc::direction_type dir)
00092 {
00093 star_matrix();
00094 if (dir == misc::backward)
00095 backward_remove();
00096 else
00097 forward_remove();
00098 }
00099
00100 private:
00101
00102
00103 void star_matrix()
00104 {
00105 for (int r = 0; r < size; r++)
00106 {
00107 result_not_computable_if(!m_semiring_elt[r][r].starable());
00108
00109 semiring_elt_t w = m_semiring_elt[r][r].star();
00110 m_semiring_elt[r][r] = w;
00111 for (int i = 0; i < size; i++)
00112 if (i != r)
00113 {
00114 semiring_elt_t z = m_semiring_elt[i][r] * w;
00115 m_semiring_elt[i][r] = z;
00116 if (z != semiring_elt_zero)
00117 for (int j = 0; j < size; j++)
00118 if (j != r)
00119 m_semiring_elt[i][j] += z * m_semiring_elt[r][j];
00120 }
00121 for (int j = 0; j < size; j++)
00122 if (j != r)
00123 m_semiring_elt[r][j] = w * m_semiring_elt[r][j];
00124 }
00125 }
00126
00127 void backward_remove()
00128 {
00129
00130
00131 vector_series_t m_wfinal (size, null_series);
00132 for_all_const_final_states(p, a)
00133 m_wfinal[state_to_index[*p]] = a.get_final(*p);
00134 a.clear_final();
00135
00136
00137 for_all_const_states(s, a)
00138 {
00139 std::list<htransition_t> transition_list;
00140 for (rdelta_iterator e(a.value(), *s); ! e.done(); e.next())
00141 transition_list.push_back(*e);
00142 int dst = state_to_index[*s];
00143 for_all_const_(std::list<htransition_t>, e, transition_list)
00144 {
00145 int src = state_to_index[a.src_of(*e)];
00146 series_set_elt_t t = a.series_of(*e);
00147 for (int k = 0; k < size; k++)
00148 {
00149 semiring_elt_t w = m_semiring_elt[k][src];
00150 if (w != semiring_elt_zero)
00151 a.add_series_transition(index_to_state[k], *s, w * t);
00152 }
00153 a.del_transition(*e);
00154 }
00155 series_set_elt_t tw = null_series;
00156 for (int k = 0; k < size; k++)
00157 tw += m_semiring_elt[dst][k] * m_wfinal[k];
00158 if (tw != null_series)
00159 a.set_final(*s, tw);
00160 }
00161 }
00162
00163 void forward_remove()
00164 {
00165
00166
00167 vector_series_t m_winitial (size, null_series);
00168 for_all_const_initial_states(p, a)
00169 m_winitial[state_to_index[*p]] = a.get_initial(*p);
00170 a.clear_initial();
00171
00172
00173 for_all_const_states(s, a)
00174 {
00175 std::list<htransition_t> transition_list;
00176 for (delta_iterator e(a.value(), *s); ! e.done(); e.next())
00177 transition_list.push_back(*e);
00178 int src = state_to_index[*s];
00179 for_all_const_(std::list<htransition_t>, e, transition_list)
00180 {
00181 int dst = state_to_index[a.dst_of(*e)];
00182 series_set_elt_t t = a.series_of(*e);
00183 for (int k = 0; k < size; k++)
00184 {
00185 semiring_elt_t w = m_semiring_elt[dst][k];
00186 if (w != semiring_elt_zero)
00187 a.add_series_transition(*s, index_to_state[k], t * w);
00188 }
00189 a.del_transition(*e);
00190 }
00191 series_set_elt_t tw = null_series;
00192 for (int k = 0; k < size; k++)
00193 tw += m_winitial[k] * m_semiring_elt[k][src];
00194 if (tw != null_series)
00195 a.set_initial(*s, tw);
00196 }
00197 }
00198
00199
00200 automaton_t& a;
00201
00202
00203 int size;
00204
00205
00206 series_set_elt_t null_series;
00207 semiring_elt_t semiring_elt_zero;
00208 monoid_elt_t monoid_identity;
00209
00210
00211 matrix_semiring_elt_t m_semiring_elt;
00212
00213
00214 std::vector<hstate_t> index_to_state;
00215 std::map<hstate_t, int> state_to_index;
00216 };
00217
00218
00219
00220
00221
00222
00223 template <typename Auto>
00224 class Finder
00225 {
00226 AUTOMATON_TYPES(Auto);
00227
00228 public:
00229 Finder (const automaton_t& aut)
00230 : a_(aut)
00231 {
00232 for_all_const_transitions(t, a_)
00233 map_[make_pair(a_.src_of(*t), make_pair(a_.label_of(*t),
00234 a_.dst_of(*t)))] = true;
00235 }
00236
00237 void insert(const hstate_t src, const label_t l, const hstate_t dst)
00238 {
00239 map_[make_pair(src, make_pair(l, dst))] = true;
00240 }
00241
00242 bool operator() (const hstate_t src, const label_t l, const hstate_t dst)
00243 {
00244 return map_[make_pair(src, make_pair(l, dst))];
00245 }
00246
00247 private:
00248 const automaton_t& a_;
00249 std::map<std::pair<hstate_t, std::pair<label_t, hstate_t> >, bool> map_;
00250 };
00251
00252
00253
00254
00255
00256
00257
00258 template <class A_, typename Auto>
00259 class EpsilonRemover<A_, Auto, bool>
00260 {
00261 AUTOMATON_TYPES(Auto);
00262 typedef std::vector<std::vector<semiring_elt_t> > matrix_semiring_elt_t;
00263 typedef std::vector<series_set_elt_t> vector_series_t;
00264 typedef std::queue<htransition_t> tr_queue_t;
00265 typedef std::queue<hstate_t> state_queue_t;
00266 typedef std::vector<htransition_t> ctransitions_t;
00267 typedef std::vector<hstate_t> cstates_t;
00268
00269 public:
00270 EpsilonRemover(const AutomataBase<A_>&,
00271 Auto& aut)
00272 : a(aut),
00273 null_series(aut.series().zero_),
00274 semiring_elt_zero(aut.series().semiring().wzero_),
00275 monoid_identity(aut.series().monoid().VCSN_EMPTY_)
00276 {
00277 for_all_const_transitions(t, a)
00278 tr_q.push(*t);
00279 }
00280
00281 void operator() (misc::direction_type dir)
00282 {
00283 if (dir == misc::forward)
00284 forward_closure();
00285 else
00286 backward_closure();
00287 suppress_epsilon_transitions();
00288 }
00289
00290 void suppress_epsilon_transitions ()
00291 {
00292 for_all_transitions(t, a)
00293 {
00294 series_set_elt_t s = a.series_of(*t);
00295 if (s.get(monoid_identity) == semiring_elt_zero)
00296 continue;
00297
00298 s.assoc(monoid_identity.value(), semiring_elt_zero.value());
00299 if (s != null_series)
00300 a.add_series_transition(a.src_of(*t), a.dst_of(*t), s);
00301 a.del_transition(*t);
00302 }
00303 }
00304
00305 void forward_closure ()
00306 {
00307
00308 Finder<automaton_t> find(a);
00309 cstates_t st_out;
00310
00311 while (!tr_q.empty())
00312 {
00313 htransition_t t = tr_q.front();
00314 hstate_t src = a.src_of(t);
00315 hstate_t mid = a.dst_of(t);
00316 label_t l = a.label_of(t);
00317
00318 st_out.clear();
00319 for (delta_iterator t(a.value(), mid); ! t.done(); t.next())
00320 if (a.is_spontaneous(*t))
00321 st_out.push_back(a.dst_of(*t));
00322 for_all_const(typename cstates_t, dst, st_out)
00323 {
00324 if (!find(src, l, *dst))
00325 {
00326 htransition_t new_tr = a.add_transition(src, *dst, l);
00327 tr_q.push(new_tr);
00328 find.insert(src, l, *dst);
00329 }
00330 }
00331 tr_q.pop();
00332 }
00333
00334 state_queue_t sq;
00335
00336 for_all_const_initial_states(s, a)
00337 sq.push(*s);
00338 while (!sq.empty())
00339 {
00340 hstate_t i = sq.front();
00341
00342 st_out.clear();
00343 for (delta_iterator t(a.value(), i); ! t.done(); t.next())
00344 if (a.is_spontaneous(*t))
00345 st_out.push_back(a.dst_of(*t));
00346 for_all_const(typename cstates_t, s, st_out)
00347 {
00348 if (!a.is_initial(*s))
00349 {
00350 a.set_initial(*s);
00351 sq.push(*s);
00352 }
00353 }
00354 sq.pop();
00355 }
00356 }
00357
00358 void backward_closure ()
00359 {
00360
00361 Finder<automaton_t> find(a);
00362 cstates_t st_in;
00363
00364 while (!tr_q.empty())
00365 {
00366 htransition_t t = tr_q.front();
00367 hstate_t mid = a.src_of(t);
00368 hstate_t dst = a.dst_of(t);
00369 label_t l = a.label_of(t);
00370
00371 st_in.clear();
00372 for (rdelta_iterator t(a.value(), mid); ! t.done(); t.next())
00373 if (a.is_spontaneous(*t))
00374 st_in.push_back(a.src_of(*t));
00375 for_all_const(typename cstates_t, src, st_in)
00376 {
00377 if (!find(*src, l, dst))
00378 {
00379 htransition_t new_tr = a.add_transition(*src, dst, l);
00380 tr_q.push(new_tr);
00381 find.insert(*src, l, dst);
00382 }
00383 }
00384 tr_q.pop();
00385 }
00386
00387 state_queue_t sq;
00388
00389 for_all_const_final_states(s, a)
00390 sq.push(*s);
00391 while (!sq.empty())
00392 {
00393 hstate_t i = sq.front();
00394
00395 st_in.clear();
00396 for (rdelta_iterator t(a.value(), i); ! t.done(); t.next())
00397 if (a.is_spontaneous(*t))
00398 st_in.push_back(a.src_of(*t));
00399 for_all_const(typename cstates_t, s, st_in)
00400 {
00401 if (!a.is_final(*s))
00402 {
00403 a.set_final(*s);
00404 sq.push(*s);
00405 }
00406 }
00407 sq.pop();
00408 }
00409 }
00410
00411 private:
00412 automaton_t& a;
00413
00414
00415 const series_set_elt_t null_series;
00416 const semiring_elt_t semiring_elt_zero;
00417 const monoid_elt_t monoid_identity;
00418
00419
00420 tr_queue_t tr_q;
00421 };
00422
00423
00424
00425
00426
00427
00428 template<class A_, typename Auto, typename Weight>
00429 void
00430 do_eps_removal_here(const AutomataBase<A_>& a_set,
00431 const Weight&,
00432 Auto& a,
00433 misc::direction_type dir)
00434 {
00435 BENCH_TASK_SCOPED("eps_removal");
00436
00437 EpsilonRemover<A_, Auto, Weight> algo(a_set, a);
00438 algo(dir);
00439 }
00440
00441 template<typename A, typename AI>
00442 void
00443 eps_removal_here(Element<A, AI>& a, misc::direction_type dir)
00444 {
00445 typedef Element<A, AI> automaton_t;
00446 AUTOMATON_TYPES(automaton_t);
00447
00448 do_eps_removal_here(a.structure(),
00449 SELECT(semiring_elt_value_t),
00450 a, dir);
00451 }
00452
00453 template<typename A, typename AI>
00454 Element<A, AI>
00455 eps_removal(const Element<A, AI>& a, misc::direction_type dir)
00456 {
00457 typedef Element<A, AI> automaton_t;
00458 AUTOMATON_TYPES(automaton_t);
00459
00460 automaton_t ret(a);
00461 do_eps_removal_here(ret.structure(),
00462 SELECT(semiring_elt_value_t),
00463 ret, dir);
00464 return ret;
00465 }
00466
00467 template<typename A, typename AI>
00468 void
00469 backward_eps_removal_here(Element<A, AI>& a)
00470 {
00471 typedef Element<A, AI> automaton_t;
00472 AUTOMATON_TYPES(automaton_t);
00473
00474 do_eps_removal_here(a.structure(),
00475 SELECT(semiring_elt_value_t),
00476 a, misc::backward);
00477 }
00478
00479 template<typename A, typename AI>
00480 Element<A, AI>
00481 backward_eps_removal(const Element<A, AI>& a)
00482 {
00483 typedef Element<A, AI> automaton_t;
00484 AUTOMATON_TYPES(automaton_t);
00485
00486 automaton_t ret(a);
00487 do_eps_removal_here(ret.structure(),
00488 SELECT(semiring_elt_value_t),
00489 ret, misc::backward);
00490 return ret;
00491 }
00492
00493 template<typename A, typename AI>
00494 void
00495 forward_eps_removal_here(Element<A, AI>& a)
00496 {
00497 typedef Element<A, AI> automaton_t;
00498 AUTOMATON_TYPES(automaton_t);
00499
00500 do_eps_removal_here(a.structure(),
00501 SELECT(semiring_elt_value_t),
00502 a, misc::forward);
00503 }
00504
00505 template<typename A, typename AI>
00506 Element<A, AI>
00507 forward_eps_removal(const Element<A, AI>& a)
00508 {
00509 typedef Element<A, AI> automaton_t;
00510 AUTOMATON_TYPES(automaton_t);
00511
00512 automaton_t ret(a);
00513 do_eps_removal_here(ret.structure(),
00514 SELECT(semiring_elt_value_t),
00515 ret, misc::forward);
00516 return ret;
00517 }
00518
00519 }
00520
00521 #endif // ! VCSN_ALGORITHMS_EPS_REMOVAL_HXX