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