00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_REALTIME_HXX
00018 # define VCSN_ALGORITHMS_REALTIME_HXX
00019
00020 # include <vaucanson/algorithms/realtime.hh>
00021
00022 # include <vaucanson/algorithms/eps_removal.hh>
00023 # include <vaucanson/algorithms/accessible.hh>
00024 # include <vaucanson/algorithms/cut_up.hh>
00025
00026 # include <vaucanson/automata/concept/automata_base.hh>
00027
00028 # include <deque>
00029 # include <set>
00030
00031 namespace vcsn {
00032
00033
00034
00035
00036
00037
00038 template <class Auto, class Label>
00039 int do_realtime_words(Auto& a,
00040 typename Auto::hstate_t start,
00041 typename Auto::hstate_t stop,
00042 const Label& label, bool initial, bool final)
00043 {
00044 AUTOMATON_TYPES(Auto);
00045 hstate_t s1;
00046 semiring_elt_t s_ident = algebra::identity_as<semiring_elt_value_t>
00047 ::of(a.structure().series().semiring());
00048
00049
00050 if (label.supp().begin() == label.supp().end())
00051 return 0;
00052
00053 monoid_elt_t m1(a.structure().series().monoid(), *label.supp().begin());
00054 monoid_elt_value_t w1 = m1.value();
00055
00056 unsigned int size = m1.length();
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 typename monoid_elt_t::iterator l = m1.begin();
00065
00066 m = *l;
00067
00068 in_series.assoc(m, s);
00069
00070 if (initial)
00071 {
00072 hstate_t s0 = a.add_state();
00073 a.set_initial(s0, in_series);
00074 a.unset_initial(stop);
00075 s1 = s0;
00076 }
00077 else
00078 {
00079 hstate_t s0 = start;
00080 s1 = a.add_state();
00081 a.add_series_transition(s0, s1, in_series);
00082 }
00083
00084 l++;
00085 for (typename monoid_elt_t::iterator end = m1.begin() + (size - 1);
00086 l != end; ++l)
00087 {
00088 m = *l;
00089 hstate_t s0 = s1;
00090 s1 = a.add_state();
00091 series_set_elt_t series(a.structure().series());
00092 series.assoc(m, s_ident);
00093 a.add_series_transition(s0, s1, series);
00094 }
00095
00096 m = *l;
00097
00098 series_set_elt_t out_series(a.structure().series());
00099 out_series.assoc(m, s_ident);
00100
00101 if (final)
00102 {
00103 a.unset_final(start);
00104 a.set_final(s1, out_series);
00105 }
00106 else
00107 a.add_series_transition(s1, stop, out_series);
00108
00109 return 1;
00110 }
00111
00112 return 0;
00113 }
00114
00115
00116 template <class S, class T>
00117 void realtime_words_here(Element<S, T>& res)
00118 {
00119 typedef Element<S, T> auto_t;
00120 AUTOMATON_TYPES(auto_t);
00121 typedef std::vector<hstate_t> vector_t;
00122
00123
00124 cut_up_here(res);
00125
00126 vector_t tmp;
00127 tmp.reserve(res.initial().size());
00128 for_all_const_initial_states(i, res)
00129 tmp.push_back(*i);
00130 for_all(typename vector_t, i, tmp)
00131 do_realtime_words(res, hstate_t(), *i, res.get_initial(*i), true, false);
00132 tmp.clear();
00133 for_all_const_final_states(f, res)
00134 tmp.push_back(*f);
00135 for_all(typename vector_t, f, tmp)
00136 do_realtime_words(res, *f, hstate_t(), res.get_final(*f), false, true);
00137
00138 transitions_t transitions = res.transitions();
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
00147
00148
00149
00150 template <class A_, typename Auto_>
00151 bool
00152 do_is_realtime(const AutomataBase<A_>&, const Auto_& a)
00153 {
00154 TIMER_SCOPED("is_realtime (automaton)");
00155 AUTOMATON_TYPES(Auto_);
00156 for_all_const_transitions(e, a)
00157 if (!is_support_in_alphabet(a.series_of(*e)))
00158 return false;
00159 return true;
00160 }
00161
00162
00163
00164
00165
00166
00167 template<typename Auto_, typename A_>
00168 void
00169 do_realtime_here(const AutomataBase<A_>&, Auto_& a,
00170 misc::direction_type type = misc::forward)
00171 {
00172 realtime_words_here(a);
00173
00174 eps_removal_here(a, type);
00175
00176 if (type == misc::forward)
00177 coaccessible_here(a);
00178 else
00179 accessible_here(a);
00180 }
00181
00182
00183 template<typename S, typename T>
00184 void
00185 realtime_here(Element<S, T>& a, misc::direction_type type)
00186 {
00187 do_realtime_here(a.structure(), a, type);
00188 }
00189
00190
00191
00192
00193
00194
00195 template<typename Auto_, typename A_>
00196 Auto_
00197 do_realtime(const AutomataBase<A_>&b,
00198 const Auto_& a,
00199 misc::direction_type type = misc::forward)
00200 {
00201 Auto_ ret(a);
00202 do_realtime_here(b, ret, type);
00203 return ret;
00204 }
00205
00206 template<typename A, typename T>
00207 Element<A, T>
00208 realtime(const Element<A, T>& a, misc::direction_type type)
00209 {
00210 return do_realtime(a.structure(), a, type);
00211 }
00212
00213
00214 }
00215
00216 #endif // ! VCSN_ALGORITHMS_REALTIME_HXX