00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_ONE_EPS_CLOSURE_HXX
00018 # define VCSN_ALGORITHMS_ONE_EPS_CLOSURE_HXX
00019
00020 # include <vaucanson/algorithms/one_eps_closure.hh>
00021
00022 # include <vaucanson/automata/concept/automata_base.hh>
00023 # include <vaucanson/misc/usual_macros.hh>
00024 # include <list>
00025
00026 namespace vcsn
00027 {
00028
00029 template<typename A, typename AI, typename S, typename V>
00030 void
00031 workaround_add_series_transition(const AutomataBase<A>& a_set,
00032 Element<A, AI>& a,
00033 S& src, S& dst, V& val)
00034 {
00035 typedef Element<A, AI> automaton_t;
00036 AUTOMATON_TYPES(automaton_t)
00037
00038
00039
00040
00041
00042 for (delta_iterator j(a.value(), src); !j.done(); j.next())
00043 {
00044 if (a.dst_of(*j) != dst)
00045 {
00046 continue;
00047 }
00048 else
00049 {
00050 val += a.series_of(*j);
00051 a.del_transition(*j);
00052 break;
00053 }
00054 }
00055 a.add_series_transition(src, dst, val);
00056 }
00057
00058
00059
00060
00061
00062
00063 template<class A, typename AI, typename EPS>
00064 void
00065 do_backward_one_eps_closure(const AutomataBase<A>& a_set,
00066 Element<A, AI>& a,
00067 const EPS& eps)
00068 {
00069 typedef Element<A, AI> automaton_t;
00070 AUTOMATON_TYPES(automaton_t)
00071
00072 hstate_t source = eps.src();
00073 hstate_t dest = eps.dst();
00074
00075 precondition(source != dest);
00076
00077
00078
00079
00080
00081 std::list<htransition_t> transition_list;
00082 for (delta_iterator it(a.value(), dest); !it.done(); it.next())
00083 transition_list.push_back(*it);
00084
00085
00086 for(typename std::list<htransition_t>::iterator it =
00087 transition_list.begin(); it != transition_list.end(); ++it)
00088 {
00089 series_set_elt_t series = eps.weight() * a.series_of(*it);
00090
00091 if (series == a.series().zero_)
00092 continue;
00093
00094 hstate_t target = a.dst_of(*it);
00095
00096 workaround_add_series_transition(a.structure(), a,
00097 source, target, series);
00098 }
00099
00100
00101
00102 series_set_elt_t fin_weight =
00103 a.get_final(source) + eps.weight() * a.get_final(dest);
00104
00105 a.set_final(source, fin_weight);
00106 }
00107
00108 template<class A, typename AI, typename EPS>
00109 void
00110 do_forward_one_eps_closure(const AutomataBase<A>& a_set,
00111 Element<A, AI>& a,
00112 const EPS& eps)
00113 {
00114 typedef Element<A, AI> automaton_t;
00115 AUTOMATON_TYPES(automaton_t);
00116
00117 hstate_t source = eps.src();
00118 hstate_t dest = eps.dst();
00119
00120 precondition(source != dest);
00121
00122
00123
00124
00125
00126 std::list<htransition_t> transition_list;
00127 for (rdelta_iterator it(a.value(), source); ! it.done(); it.next())
00128 transition_list.push_back(*it);
00129
00130
00131 for(typename std::list<htransition_t>::iterator it =
00132 transition_list.begin(); it != transition_list.end(); ++it)
00133 {
00134 series_set_elt_t series = a.series_of(*it) * eps.weight();
00135
00136 if (series == a.series().zero_)
00137 continue;
00138
00139 hstate_t target = a.dst_of(*it);
00140
00141 workaround_add_series_transition(a.structure(), a,
00142 source, target, series);
00143 }
00144
00145
00146 series_set_elt_t ini_weight =
00147 a.get_initial(source) * eps.weight() + a.get_initial(dest);
00148 a.set_initial(dest, ini_weight);
00149 }
00150
00151 template<typename A, typename AI, typename EPS>
00152 void
00153 backward_one_eps_closure(Element<A, AI>& a, const EPS& eps)
00154 {
00155 typedef Element<A, AI> automaton_t;
00156 AUTOMATON_TYPES(automaton_t);
00157 do_backward_one_eps_closure(a.structure(), a, eps);
00158 }
00159
00160 template<typename A, typename AI, typename EPS>
00161 void
00162 forward_one_eps_closure(Element<A, AI>& a, const EPS& eps)
00163 {
00164 typedef Element<A, AI> automaton_t;
00165 AUTOMATON_TYPES(automaton_t);
00166 do_forward_one_eps_closure(a.structure(), a, eps);
00167 }
00168
00169 template<typename A, typename AI, typename EPS>
00170 void
00171 one_eps_closure(Element<A, AI>& a, const EPS& eps, misc::direction_type dir)
00172 {
00173 typedef Element<A, AI> automaton_t;
00174 AUTOMATON_TYPES(automaton_t);
00175 switch(dir){
00176 case misc::backward :
00177 do_backward_one_eps_closure(a.structure(), a, eps);
00178 break;
00179 case misc::forward :
00180 do_forward_one_eps_closure(a.structure(), a, eps);
00181 break;
00182 }
00183 }
00184
00185 }
00186
00187 #endif // ! VCSN_ALGORITHMS_ONE_EPS_CLOSURE_HXX