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