00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_BACKWARD_REALTIME_HXX
00018 # define VCSN_ALGORITHMS_BACKWARD_REALTIME_HXX
00019
00020 # include <vaucanson/algorithms/backward_realtime.hh>
00021 # include <vaucanson/algorithms/cut_up.hh>
00022
00023 # include <vaucanson/automata/concept/automata_base.hh>
00024 # include <vaucanson/algorithms/eps_removal.hh>
00025 # include <vaucanson/algorithms/accessible.hh>
00026
00027 # include <queue>
00028 # include <set>
00029
00030 namespace vcsn {
00031
00032
00033
00034
00035
00036
00037
00038 template <class Auto, class Label>
00039 int do_realtime_words(Auto& a,
00040 hstate_t start, hstate_t stop,
00041 const Label& label, bool initial, bool final)
00042 {
00043 AUTOMATON_TYPES(Auto);
00044 hstate_t s1;
00045
00046 semiring_elt_t s_ident =
00047 algebra::identity_as<semiring_elt_value_t>
00048 ::of(a.structure().series().semiring());
00049
00050 monoid_elt_t m1(a.structure().series().monoid(), *label.supp().begin());
00051 monoid_elt_value_t w1 = m1.value();
00052
00053 int cpt = 0;
00054
00055 unsigned int size = w1.size();
00056
00057 if (size > 1)
00058 {
00059 monoid_elt_t m(a.structure().series().monoid());
00060
00061 semiring_elt_t s = label.get(m1);
00062 series_set_elt_t in_series(a.structure().series());
00063
00064 m = w1.substr(cpt++, 1);
00065
00066 in_series.assoc(m, s);
00067
00068 if (initial)
00069 {
00070 hstate_t s0 = a.add_state();
00071 a.set_initial(s0, in_series);
00072 a.unset_initial(stop);
00073 s1 = s0;
00074 }
00075 else
00076 {
00077 hstate_t s0 = start;
00078 s1 = a.add_state();
00079 a.add_series_transition(s0, s1, in_series);
00080 }
00081
00082 for (unsigned int i = 1; i < size - 1; ++i)
00083 {
00084 m = w1.substr(cpt++, 1);
00085 hstate_t s0 = s1;
00086 s1 = a.add_state();
00087 series_set_elt_t series(a.structure().series());
00088 series.assoc(m, s_ident);
00089 a.add_series_transition(s0, s1, series);
00090 }
00091
00092 m = w1.substr(cpt++, 1);
00093
00094 series_set_elt_t out_series(a.structure().series());
00095 out_series.assoc(m, s_ident);
00096
00097 if (final)
00098 {
00099 a.unset_final(start);
00100 a.set_final(s1, out_series);
00101 }
00102 else
00103 a.add_series_transition(s1, stop, out_series);
00104
00105 return 1;
00106 }
00107
00108 return 0;
00109 }
00110
00111
00112 template <class S, class T>
00113 void realtime_words_here(Element<S, T>& res)
00114 {
00115 typedef Element<S, T> auto_t;
00116 AUTOMATON_TYPES(auto_t);
00117 typedef std::vector<hstate_t> vector_t;
00118
00119
00120 cut_up_here(res);
00121
00122 transitions_t transitions = res.transitions();
00123 vector_t i_states; i_states.reserve(res.initial().size());
00124 vector_t f_states; f_states.reserve(res.final().size());
00125
00126 for_all_initial_states(f, res)
00127 i_states.push_back(*f);
00128 for_all_final_states(i, res)
00129 f_states.push_back(*i);
00130
00131 for_all_(vector_t, i, i_states)
00132 do_realtime_words(res, hstate_t(), *i,
00133 res.get_initial(*i), true, false);
00134
00135 for_all_(vector_t, f, f_states)
00136 do_realtime_words(res, *f, hstate_t(),
00137 res.get_final(*f), false, true);
00138
00139 for_all_(transitions_t, e, transitions)
00140 if (do_realtime_words(res, res.src_of(*e), res.dst_of(*e),
00141 res.series_of(*e), false, false))
00142 res.del_transition(*e);
00143 }
00144
00145
00146 template <class A_, typename Auto_>
00147 void
00148 do_backward_realtime_here(const AutomataBase<A_>&, Auto_& a)
00149 {
00150 AUTOMATON_TYPES(Auto_);
00151 typedef std::set<htransition_t> delta_ret_t;
00152 typedef std::deque<htransition_t> queue_t;
00153
00154 queue_t to_del, origin_d;
00155 delta_ret_t aim_d;
00156 monoid_elt_t monoid_identity =
00157 algebra::identity_as<monoid_elt_value_t>::
00158 of(a.structure().series().monoid());
00159 semiring_elt_t semiring_zero =
00160 algebra::zero_as<semiring_elt_value_t>::
00161 of(a.structure().series().semiring());
00162 series_set_elt_t series_identity =
00163 algebra::identity_as<series_set_elt_value_t>::of(a.structure().series());
00164
00165 backward_eps_removal_here(a);
00166
00167 for (typename automaton_t::state_iterator origin = a.states().begin();
00168 origin != a.states().end();
00169 ++origin)
00170 {
00171 std::insert_iterator<queue_t> origin_i(origin_d, origin_d.begin());
00172 a.delta(origin_i, *origin, delta_kind::transitions());
00173
00174 while (!origin_d.empty())
00175 {
00176 htransition_t d_o = origin_d.front();
00177 origin_d.pop_front();
00178 if (a.series_of(d_o).get(monoid_identity) != semiring_zero)
00179 {
00180 aim_d.clear();
00181 a.deltac(aim_d, a.dst_of(d_o), delta_kind::transitions());
00182 for (typename delta_ret_t::const_iterator d = aim_d.begin();
00183 d != aim_d.end();
00184 ++d)
00185 if (a.series_of(*d).get(monoid_identity) == semiring_zero)
00186 {
00187 bool new_transition = true;
00188 for (typename queue_t::const_iterator d__o =
00189 origin_d.begin();
00190 d__o != origin_d.end();
00191 ++d__o)
00192 if ((a.dst_of(*d__o) == a.dst_of(*d) &&
00193 (a.label_of(*d__o) == a.label_of(*d))))
00194 {
00195 new_transition = false;
00196 break;
00197 }
00198
00199 if (new_transition)
00200 {
00201 htransition_t new_htransition = a.add_series_transition
00202 (*origin,
00203 a.dst_of(*d),
00204 a.series_of(d_o) * a.series_of(*d));
00205 origin_d.push_back(new_htransition);
00206 }
00207 }
00208 if (a.is_final(a.dst_of(d_o)))
00209 a.set_final(*origin);
00210 }
00211 }
00212 }
00213
00214 for (typename automaton_t::transition_iterator e = a.transitions().begin();
00215 e != a.transitions().end();
00216 ++e)
00217 if (a.series_of(*e).get(monoid_identity) != semiring_zero)
00218 to_del.push_back(*e);
00219
00220 while (!to_del.empty())
00221 {
00222 htransition_t e = to_del.front();
00223 to_del.pop_front();
00224 a.del_transition(e);
00225 }
00226
00227 accessible_here(a);
00228
00229 realtime_words_here(a);
00230 }
00231
00232
00233 template<typename A, typename T>
00234 void
00235 backward_realtime_here(Element<A, T>& a)
00236 {
00237 do_backward_realtime_here(a.structure(), a);
00238 }
00239
00240 template <class A_, typename Auto_>
00241 Auto_
00242 do_backward_realtime(const AutomataBase<A_>&, const Auto_& a)
00243 {
00244 Auto_ ret(a);
00245 do_backward_realtime_here(ret.structure(), ret);
00246 return ret;
00247 }
00248
00249 template<typename A, typename T>
00250 Element<A, T>
00251 backward_realtime(const Element<A, T>& a)
00252 {
00253 return do_backward_realtime(a.structure(), a);
00254 }
00255
00256 }
00257
00258 #endif // ! VCSN_ALGORITHMS_BACKWARD_REALTIME_HXX