Vaucanson 1.4
|
00001 // evaluation.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, 2009 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_EVALUATION_HXX 00018 # define VCSN_ALGORITHMS_EVALUATION_HXX 00019 00020 # include <vaucanson/algorithms/internal/evaluation.hh> 00021 00022 # include <vaucanson/misc/usual_macros.hh> 00023 # include <vaucanson/automata/concept/transducer_base.hh> 00024 00025 // FIXME: check dead code 00026 //# include <vaucanson/algorithms/standard.hh> 00027 00028 # include <vaucanson/algorithms/standard_of.hh> 00029 00030 // Required by DefaultChooser. 00031 # include <vaucanson/algorithms/aut_to_exp.hh> 00032 00033 # include <vaucanson/algorithms/extension.hh> 00034 # include <vaucanson/algorithms/product.hh> 00035 # include <vaucanson/algorithms/trim.hh> 00036 # include <vaucanson/algorithms/image.hh> 00037 00038 namespace vcsn 00039 { 00040 template<typename SS, typename SM, typename V, 00041 typename Series_t, typename Trans_t, 00042 typename M> 00043 void 00044 do_partial_evaluation(const algebra::Series<SS, SM>&, 00045 const Series_t& E, 00046 const TransducerBase<V>&, 00047 const Trans_t& S, 00048 const typename Trans_t::hstate_t& p, 00049 M& res) 00050 { 00051 // Type helpers. 00052 typedef typename Trans_t::value_t W; 00053 typedef typename output_projection_helper<V, W>::ret Auto_t; 00054 AUTOMATON_TYPES(Auto_t); 00055 AUTOMATON_TYPES_(Trans_t, t_); 00056 typedef typename Auto_t::set_t Auto_set_t; 00057 typedef typename Auto_set_t::series_set_t Auto_series_set_t; 00058 typedef series_set_elt_t exp_t; 00059 typedef t_series_set_elt_t t_exp_t; 00060 typedef std::map<t_hstate_t, std::pair<t_hstate_t, t_hstate_t> > 00061 state_pair_map_t; 00062 typedef std::map<t_hstate_t, hstate_t> state_state_map_t; 00063 typedef std::pair<t_hstate_t, exp_t> se_pair_t; 00064 Auto_set_t auto_structure(Auto_series_set_t(S.structure().series().semiring())); 00065 00066 // 00067 // Part 1. 00068 // Construct A = standard_of(E). 00069 // 00070 00071 // Hold standard_of(E). 00072 Auto_t A(auto_structure); 00073 standard_of(A, E.value()); 00074 00075 // 00076 // Part 2. 00077 // Sp construction. 00078 // 00079 00080 // Does a copy of S, 00081 Trans_t Sp = S; 00082 state_state_map_t Sp_to_S; 00083 for_all_const_states_(t_, q, Sp) 00084 { 00085 hstate_t pSp = Sp_to_S[*q] = S.get_state(size_t(*q)); 00086 if (pSp == p) 00087 Sp.set_initial(*q); 00088 else 00089 Sp.unset_initial(*q); 00090 } 00091 00092 // 00093 // evaluation(A, Sp) 00094 // Evaluation: we keep some information for later. 00095 // 00096 00097 // extension 00098 Trans_t tmp_trans(Sp.structure()); 00099 tmp_trans = extension(A, Sp); 00100 00101 // product 00102 Trans_t pro(Sp.structure()); 00103 state_pair_map_t sp_m; 00104 pro = product(tmp_trans, Sp, sp_m); 00105 00106 // build map we will reuse later 00107 std::map<typename Trans_t::hstate_t, typename Trans_t::hstate_t> states_map_for_sp_m; 00108 for_all_iterator (typename state_pair_map_t::iterator, i, sp_m) 00109 states_map_for_sp_m.insert(std::make_pair(pro.get_state(size_t(i->first)), i->first)); 00110 00111 // image 00112 Auto_t G(auto_structure); 00113 state_state_map_t proj_m; 00114 G = image(pro, proj_m); 00115 00116 std::map<typename Trans_t::hstate_t, typename Trans_t::hstate_t> states_map_for_proj_m; 00117 for_all_iterator (typename state_state_map_t::iterator, i, proj_m) 00118 states_map_for_proj_m.insert(std::make_pair(G.get_state(size_t(i->first)), i->first)); 00119 00120 // add i state 00121 const hstate_t i = G.add_state(); 00122 for_all_const_initial_states(r, G) 00123 { 00124 exp_t old_label = G.get_initial(*r); 00125 G.add_series_transition(i, *r, old_label); 00126 G.unset_initial(*r); 00127 } 00128 G.set_initial(i); 00129 00130 // 00131 // Part 3. 00132 // Initialize map. 00133 // 00134 00135 G.clear_final(); 00136 state_state_map_t state_of, is_state_of; 00137 for_all_const_states_(t_, u, Sp) 00138 { 00139 hstate_t new_state = G.add_state(); 00140 state_of[*u] = new_state; 00141 is_state_of[new_state] = *u; 00142 G.set_final(new_state); 00143 } 00144 00145 // 00146 // Part 4. 00147 // Create spontaneous transitions. 00148 // 00149 00150 for_all_const_states(ig, G) 00151 { 00152 if (*ig != i && !G.is_final(*ig)) 00153 { 00154 t_hstate_t t = sp_m[states_map_for_sp_m[proj_m[states_map_for_proj_m[*ig]]]].first; 00155 t_hstate_t u = sp_m[states_map_for_sp_m[proj_m[states_map_for_proj_m[*ig]]]].second; 00156 00157 if (tmp_trans.is_final(t)) 00158 G.add_spontaneous(*ig, state_of[u]); 00159 } 00160 } 00161 00162 // 00163 // Part 5. 00164 // Construct the output map. 00165 // 00166 00167 M se; 00168 partial_elimination(G, se); 00169 00170 for_all_(M, p, se) 00171 { 00172 se_pair_t my_pair = std::make_pair(Sp_to_S[is_state_of[(*p).first]], p->second); 00173 res.insert(my_pair); 00174 } 00175 } 00176 00177 template <typename S1, typename T1, 00178 typename S2, typename T2, 00179 typename M> 00180 void 00181 partial_evaluation(const Element<S1, T1>& E, 00182 const Element<S2, T2>& S, 00183 const typename Element<S2, T2>::hstate_t& p, 00184 M& res) 00185 { 00186 do_partial_evaluation(E.structure(), E, S.structure(), S, p, res); 00187 } 00188 00189 template<typename S, typename Auto_t, typename M, typename Chooser_t> 00190 void 00191 do_partial_elimination(const AutomataBase<S>&, 00192 const Auto_t& a, 00193 Chooser_t chooser, 00194 M& state_exp_pair_set) 00195 { 00196 AUTOMATON_TYPES(Auto_t); 00197 typedef typename std::set<htransition_t> htransition_set_t; 00198 typedef typename Auto_t::hstate_t hstate_t; 00199 typedef std::map<hstate_t, series_set_elt_t> sums_t; 00200 00201 typename htransition_set_t::const_iterator i, j; 00202 hstate_t q; 00203 htransition_set_t transitions; 00204 00205 Auto_t b = a; 00206 00207 // Save a map linking hstates between automata a and b. 00208 // This is needed to be able to fill state_exp_pair_set with correct hstates. 00209 std::map<hstate_t, hstate_t> states_map; 00210 for (state_iterator i = a.states().begin(), j = b.states().begin(), 00211 end_ = a.states().end(); 00212 i != end_; 00213 ++i, ++j) 00214 states_map.insert(std::make_pair(*j, *i)); 00215 00216 // FIXME: check dead code 00217 // standardize(b); 00218 00219 // all final states and the initial state. 00220 int num = b.final().size() + b.initial().size(); 00221 00222 while (int(b.states().size()) != num) 00223 { 00224 series_set_elt_t loop_sum(b.series()); 00225 sums_t in_sums, out_sums; 00226 typename sums_t::iterator f; 00227 q = chooser(b); 00228 if (b.is_initial(q) || b.is_final(q)) 00229 continue; 00230 00231 transitions.clear(); 00232 for (delta_iterator e(b.value(), q); ! e.done(); e.next()) 00233 transitions.insert(*e); 00234 for (i = transitions.begin(); i != transitions.end(); i = j) 00235 { 00236 j = i; ++j; 00237 00238 if (b.dst_of(*i) == q) 00239 loop_sum += b.series_of(*i); 00240 else if ((f = out_sums.find(b.dst_of(*i))) != 00241 out_sums.end()) 00242 f->second += b.series_of(*i); 00243 else 00244 out_sums.insert(std::make_pair(b.dst_of(*i), b.series_of(*i))); 00245 b.del_transition(*i); 00246 } 00247 transitions.clear(); 00248 for (rdelta_iterator e(b.value(), q); ! e.done(); e.next()) 00249 transitions.insert(*e); 00250 for (i = transitions.begin(); i != transitions.end(); i = j) 00251 { 00252 j = i; ++j; 00253 // here all loops have already been removed 00254 if ((f = in_sums.find(b.src_of(*i))) != 00255 in_sums.end()) 00256 f->second += b.series_of(*i); 00257 else 00258 in_sums.insert(std::make_pair(b.src_of(*i), b.series_of(*i))); 00259 b.del_transition(*i); 00260 } 00261 loop_sum.star(); 00262 for_all_const_(sums_t, in, in_sums) 00263 for_all_const_(sums_t, out, out_sums) 00264 { 00265 series_set_elt_t res = in->second * loop_sum * out->second; 00266 b.add_series_transition(in->first, out->first, res); 00267 } 00268 b.del_state(q); 00269 } 00270 00271 typedef std::map<hstate_t, series_set_elt_t> se_map_t; 00272 typedef std::pair<hstate_t, series_set_elt_t> state_exp_pair_t; 00273 se_map_t se_m; 00274 00275 // maybe there are more than one transition comming to one final state 00276 // we must sum the labels 00277 for_all_transitions(e, b) 00278 { 00279 hstate_t dst = b.dst_of(*e); 00280 typename se_map_t::iterator i = se_m.find(dst); 00281 if (i == se_m.end()) 00282 se_m.insert(std::make_pair(dst, 00283 series_set_elt_t (b.structure().series(), 00284 b.label_of(*e)))); 00285 else 00286 i->second += b.label_of(*e); 00287 } 00288 00289 for_all_final_states(p, b) 00290 { 00291 typename se_map_t::iterator i = se_m.find(*p); 00292 if (i != se_m.end()) 00293 state_exp_pair_set.insert(std::make_pair(states_map[*p], i->second)); 00294 } 00295 } 00296 00297 /*------------. 00298 | elimination | 00299 `------------*/ 00300 // FIXME: add the generalized automaton precondition 00301 // preconditions : 00302 // - hope that automaton's labels are sufficient to support "star" 00303 // => in fact, generalized automaton are generally expected here. 00304 template<typename A, typename T, typename M> 00305 void 00306 partial_elimination(const Element<A, T>& a, 00307 M& state_exp_pair_set) 00308 { 00309 do_partial_elimination(a.structure(), 00310 a, 00311 DefaultChooser(), 00312 state_exp_pair_set); 00313 } 00314 00315 } // ! vcsn 00316 00317 #endif // ! VCSN_ALGORITHMS_EVALUATION_HXX