Vaucanson 1.4
|
00001 // realtime.hxx: this file is part of the Vaucanson project. 00002 // 00003 // Vaucanson, a generic library for finite state machines. 00004 // 00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The Vaucanson Group. 00006 // 00007 // This program is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU General Public License 00009 // as published by the Free Software Foundation; either version 2 00010 // of the License, or (at your option) any later version. 00011 // 00012 // The complete GNU General Public Licence Notice can be found as the 00013 // `COPYING' file in the root directory. 00014 // 00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file. 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 | do_realtime_words. | 00036 `--------------------*/ 00037 00038 template <class Auto> 00039 void do_realtime_words(Auto& a) 00040 { 00041 AUTOMATON_TYPES(Auto); 00042 hstate_t s1; 00043 semiring_elt_t s_ident = algebra::identity_as<semiring_elt_value_t> 00044 ::of(a.structure().series().semiring()); 00045 00046 typedef std::vector<htransition_t> transition_vector_t; 00047 transitions_t transitions = a.transitions(); 00048 transition_vector_t tmp_trans; 00049 for_all_(transitions_t, e, transitions) 00050 tmp_trans.push_back(*e); 00051 00052 for_all(typename transition_vector_t, e, tmp_trans) 00053 { 00054 hstate_t start = a.src_of(*e); 00055 hstate_t stop = a.dst_of(*e); 00056 series_set_elt_t label = a.series_of(*e); 00057 00058 assert(label.supp().begin() != label.supp().end()); 00059 00060 monoid_elt_t m1(a.structure().series().monoid(), *label.supp().begin()); 00061 monoid_elt_value_t w1 = m1.value(); 00062 unsigned int size = m1.length(); 00063 00064 if (size > 1) 00065 { 00066 monoid_elt_t m(a.structure().series().monoid()); 00067 00068 semiring_elt_t s = label.get(m1); 00069 series_set_elt_t in_series(a.structure().series()); 00070 typename monoid_elt_t::iterator l = m1.begin(); 00071 00072 m = *l; 00073 00074 in_series.assoc(m, s); 00075 00076 s1 = a.add_state(); 00077 a.add_series_transition(start, s1, in_series); 00078 00079 l++; 00080 for (typename monoid_elt_t::iterator end = m1.begin() + (size - 1); 00081 l != end; ++l) 00082 { 00083 m = *l; 00084 hstate_t s0 = s1; 00085 s1 = a.add_state(); 00086 series_set_elt_t series(a.structure().series()); 00087 series.assoc(m, s_ident); 00088 a.add_series_transition(s0, s1, series); 00089 } 00090 00091 m = *l; 00092 00093 series_set_elt_t out_series(a.structure().series()); 00094 out_series.assoc(m, s_ident); 00095 00096 a.add_series_transition(s1, stop, out_series); 00097 a.del_transition(*e); 00098 } 00099 } 00100 } 00101 00102 00103 template <class S, class T> 00104 void realtime_words_here(Element<S, T>& res) 00105 { 00106 typedef Element<S, T> auto_t; 00107 AUTOMATON_TYPES(auto_t); 00108 typedef std::vector<hstate_t> state_vector_t; 00109 typedef std::vector<htransition_t> transition_vector_t; 00110 state_vector_t tmp; 00111 00112 // perform cut-up. 00113 cut_up_here(res); 00114 00115 // Remove any labels from initial arrows. 00116 tmp.reserve(res.initial().size()); 00117 for_all_const_initial_states(i, res) 00118 tmp.push_back(*i); 00119 for_all(typename state_vector_t, i, tmp) 00120 { 00121 series_set_elt_t l = res.get_initial(*i); 00122 assert(l.supp().begin() != l.supp().end()); 00123 monoid_elt_t m(res.structure().series().monoid(), *l.supp().begin()); 00124 if (m.length() > 0) 00125 { 00126 hstate_t s = res.add_state(); 00127 res.add_series_transition(s, *i, l); 00128 res.set_initial(s); 00129 res.unset_initial(*i); 00130 } 00131 } 00132 tmp.clear(); 00133 00134 // Remove any labels from final arrows. 00135 tmp.reserve(res.final().size()); 00136 for_all_const_final_states(f, res) 00137 tmp.push_back(*f); 00138 for_all(typename state_vector_t, f, tmp) 00139 { 00140 series_set_elt_t l = res.get_final(*f); 00141 assert(l.supp().begin() != l.supp().end()); 00142 monoid_elt_t m(res.structure().series().monoid(), *l.supp().begin()); 00143 if (m.length() > 0) 00144 { 00145 hstate_t s = res.add_state(); 00146 res.add_series_transition(*f, s, l); 00147 res.set_final(s); 00148 res.unset_final(*f); 00149 } 00150 } 00151 00152 // Make the transitions realtime (now includes any former initial 00153 // or final labels). 00154 do_realtime_words(res); 00155 } 00156 00157 00158 00159 /*--------------. 00160 | is_realtime. | 00161 `--------------*/ 00162 template <class A, typename AI> 00163 bool 00164 do_is_realtime(const AutomataBase<A>&, const Element<A, AI>& a) 00165 { 00166 BENCH_TASK_SCOPED("is_realtime (automaton)"); 00167 typedef Element<A, AI> automaton_t; 00168 AUTOMATON_TYPES(automaton_t); 00169 for_all_const_initial_states(e, a) 00170 { 00171 series_set_elt_t l = a.get_initial(*e); 00172 if (l.supp().size() > 1) 00173 return false; 00174 // We assume that an initial transition cannot be labeled by 00175 // the empty series. In other words, l.supp().size() >= 1. 00176 assertion(l.supp().size() == 1); 00177 monoid_elt_t m(a.structure().series().monoid(), *l.supp().begin()); 00178 if (m.length() > 0) 00179 return false; 00180 } 00181 for_all_const_final_states(e, a) 00182 { 00183 series_set_elt_t l = a.get_final(*e); 00184 if (l.supp().size() > 1) 00185 return false; 00186 // We assume that a final transition cannot be labeled by 00187 // the empty series. In other words, l.supp().size() >= 1. 00188 assertion(l.supp().size() == 1); 00189 monoid_elt_t m(a.structure().series().monoid(), *l.supp().begin()); 00190 if (m.length() > 0) 00191 return false; 00192 } 00193 for_all_const_transitions(e, a) 00194 if (!is_support_in_alphabet(a.series_of(*e))) 00195 return false; 00196 return true; 00197 } 00198 00199 00200 /*--------------. 00201 | realtime_here. | 00202 `--------------*/ 00203 00204 template<typename A, typename AI> 00205 void 00206 do_realtime_here(const AutomataBase<A>&, 00207 Element<A, AI>& a, 00208 misc::direction_type dir = misc::backward) 00209 { 00210 realtime_words_here(a); 00211 00212 eps_removal_here(a, dir); 00213 00214 // FIXME: This is not wanted. See #121. 00215 if (dir == misc::forward) 00216 coaccessible_here(a); 00217 else 00218 accessible_here(a); 00219 } 00220 00221 00222 template<typename A, typename AI> 00223 void 00224 realtime_here(Element<A, AI>& a, misc::direction_type dir) 00225 { 00226 do_realtime_here(a.structure(), a, dir); 00227 } 00228 00229 00230 /*-----------. 00231 | realtime. | 00232 `-----------*/ 00233 00234 template<typename A, typename AI> 00235 Element<A, AI> 00236 do_realtime(const AutomataBase<A>& b, 00237 const Element<A, AI>& a, 00238 misc::direction_type dir = misc::backward) 00239 { 00240 Element<A, AI> ret(a); 00241 do_realtime_here(b, ret, dir); 00242 return ret; 00243 } 00244 00245 template<typename A, typename AI> 00246 Element<A, AI> 00247 realtime(const Element<A, AI>& a, misc::direction_type dir) 00248 { 00249 return do_realtime(a.structure(), a, dir); 00250 } 00251 00252 00253 } // vcsn 00254 00255 #endif // ! VCSN_ALGORITHMS_REALTIME_HXX