Vaucanson 1.4
|
00001 // extension.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 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_EXTENSION_HXX 00018 # define VCSN_ALGORITHMS_EXTENSION_HXX 00019 00020 # include <vaucanson/algorithms/extension.hh> 00021 # include <vaucanson/misc/usual_macros.hh> 00022 00023 namespace vcsn { 00024 00025 template <typename S, typename K, typename T, typename Auto_t> 00026 typename identity_transducer_helper<S, K, T>::ret 00027 do_extension(const AutomataBase<S>& s, 00028 const Auto_t& a) 00029 { 00030 AUTOMATON_TYPES(Auto_t); 00031 // ret_t is the type of the transducer returned. 00032 typedef typename identity_transducer_helper<S, K, T>::ret ret_t; 00033 00034 AUTOMATON_TYPES_(ret_t, t_); 00035 typedef typename ret_t::set_t set_t; 00036 typedef typename set_t::series_set_t o_series_set_t; 00037 typedef typename ret_t::series_set_elt_t output_series_set_elt_t; 00038 typedef typename series_set_elt_t::support_t support_t; 00039 00040 set_t 00041 ts(o_series_set_t (a.structure().series(), 00042 a.structure().series().monoid())); 00043 ret_t t_ret(ts); 00044 00045 monoid_elt_t neutre = a.series().monoid().VCSN_EMPTY_; 00046 monoid_elt_t t_neutre = t_ret.series().monoid(). 00047 identity(SELECT(typename t_monoid_elt_t::value_t)); 00048 00049 std::vector<hstate_t> conv(a.states().size()); 00050 00051 for_all_const_states (s, a) 00052 conv[t_ret.add_state()] = *s; 00053 00054 for_all_const_transitions (e, a) 00055 { 00056 series_set_elt_t t = a.series_of(*e); 00057 series_set_elt_t s(t); 00058 output_series_set_elt_t os(t_ret.structure().series()); 00059 support_t supp = s.supp(); 00060 for_all_const_(support_t, m, supp) 00061 { 00062 series_set_elt_t tmp(a.structure().series()); 00063 // try to associate the neutral monoid element with a weight 00064 // to create a series which will be a weight in the series os 00065 tmp.assoc(neutre, s.get(*m)); 00066 os.assoc(*m, tmp); 00067 } 00068 htransition_t f = t_ret.add_series_transition(conv[a.src_of(*e)], 00069 conv[a.dst_of(*e)], 00070 os); 00071 } 00072 00073 initial_iterator i; 00074 for (initial_iterator next = a.initial().begin(); 00075 next != a.initial().end();) 00076 { 00077 //We need to store the next iterator before using the current one 00078 //to avoid an invalid iterator after having called set_final. 00079 //Indeed, set_final can delete the iterator if its second parameter 00080 //is the zero of the serie. 00081 i = next; 00082 next++; 00083 00084 series_set_elt_t a_series = a.get_initial(*i); 00085 t_series_set_elt_t s; 00086 s.set(t_neutre, a_series); 00087 t_ret.set_initial(conv[*i], s); 00088 } 00089 00090 final_iterator f; 00091 for (final_iterator next = a.final().begin(); 00092 next != a.final().end();) 00093 { 00094 //We need to store the next iterator before using the current one 00095 //to avoid an invalid iterator after having called set_final. 00096 //Indeed, set_final can delete the iterator if its second parameter 00097 //is the zero of the serie. 00098 f = next; 00099 next++; 00100 series_set_elt_t a_series = a.get_final(*f); 00101 t_series_set_elt_t s; 00102 s.value_set(t_neutre, a_series); 00103 t_ret.set_final(conv[*f], s); 00104 } 00105 00106 return t_ret; 00107 } 00108 00109 template<typename S, typename K, typename T> 00110 typename identity_transducer_helper<S, K, T>::ret 00111 extension(const Element<S, T>& a) 00112 { 00113 BENCH_TASK_SCOPED("extension/1"); 00114 return do_extension(a.structure(), a); 00115 } 00116 00117 00118 /*----------------. 00119 | Two arguments. | 00120 `----------------*/ 00121 00122 00123 template<typename SA, typename ST, typename Auto_t, typename Trans_t> 00124 Trans_t do_extension(const AutomataBase<SA>&, 00125 const TransducerBase<ST>&, 00126 const Auto_t& a, 00127 const Trans_t& t) 00128 { 00129 AUTOMATON_TYPES_(Trans_t, t_); 00130 AUTOMATON_TYPES_(Auto_t, a_); 00131 typedef typename Auto_t::hstate_t hstate_t; 00132 typedef typename Trans_t::series_set_elt_t t_output_series_set_elt_t; 00133 typedef typename Auto_t::series_set_elt_t::support_t a_support_t; 00134 typedef typename Trans_t::semiring_elt_t t_weight_t; 00135 00136 Trans_t tt(t.structure()); 00137 std::map<hstate_t, hstate_t> conv; 00138 00139 a_monoid_elt_t a_neutre = 00140 a.series().monoid().identity(SELECT(typename a_monoid_elt_t::value_t)); 00141 t_monoid_elt_t t_neutre = 00142 t.series().monoid().identity(SELECT(typename t_monoid_elt_t::value_t)); 00143 00144 for(a_state_iterator p = a.states().begin(); p != a.states().end(); ++p) 00145 conv[*p] = tt.add_state(); 00146 00147 // convert transitions 00148 for(a_transition_iterator e = a.transitions().begin(); 00149 e != a.transitions().end(); ++e) 00150 { 00151 a_series_set_elt_t s_ = a.series_of(*e); 00152 a_series_set_elt_t s(s_); 00153 00154 t_output_series_set_elt_t os(t.structure().series()); 00155 00156 a_support_t supp = s.supp(); 00157 for(typename a_support_t::const_iterator m = supp.begin(); 00158 m != supp.end(); ++m) 00159 { 00160 t_weight_t tmp(t.structure().series().semiring()); 00161 tmp.assoc(a_neutre, s.get(*m)); 00162 os.assoc(a_monoid_elt_t (a.structure().series().monoid(), *m), tmp); 00163 } 00164 00165 tt.add_series_transition(conv[a.src_of(*e)], conv[a.dst_of(*e)], os); 00166 } 00167 00168 a_initial_iterator i; 00169 for (a_initial_iterator next = a.initial().begin(); 00170 next != a.initial().end();) 00171 { 00172 //We need to store the next iterator before using the current one 00173 //to avoid an invalid iterator after having called set_final. 00174 //Indeed, set_final can delete the iterator if its second parameter 00175 //is the zero of the serie. 00176 i = next; 00177 next++; 00178 a_series_set_elt_t a_series = a.get_initial(*i); 00179 t_series_set_elt_t s (t.structure().series()); 00180 s.assoc(t_neutre, a_series); 00181 tt.set_initial(conv[*i], s); 00182 } 00183 00184 a_final_iterator f; 00185 for (a_final_iterator next = a.final().begin(); 00186 next != a.final().end();) 00187 { 00188 //We need to store the next iterator before using the current one 00189 //to avoid an invalid iterator after having called set_final. 00190 //Indeed, set_final can delete the iterator if its second parameter 00191 //is the zero of the serie. 00192 f = next; 00193 next++; 00194 a_series_set_elt_t a_series = a.get_final(*f); 00195 t_series_set_elt_t s (t.structure().series()); 00196 s.assoc(t_neutre, a_series); 00197 tt.set_final(conv[*f], s); 00198 } 00199 00200 return tt; 00201 } 00202 00203 template<typename SA, typename TA, typename ST, typename TT> 00204 Element<ST, TT> 00205 extension(const Element<SA, TA>& a, const Element<ST, TT>& t) 00206 { 00207 BENCH_TASK_SCOPED("extension/2"); 00208 return do_extension(a.structure(), t.structure(), a, t); 00209 } 00210 00211 } 00212 00213 #endif // ! VCSN_ALGORITHMS_EXTENSION_HXX