- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# one_eps_closure.hxx

    00001 // one_eps_closure.hxx: this file is part of the Vaucanson project.
    00002 //
    00003 // Vaucanson, a generic library for finite state machines.
    00004 //
    00005 // Copyright (C) 2010 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_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     // We cannot update a transition with the current interface.
    00038     // Instead...
    00039     // Find the first transitions going from source to target,
    00040     // labelled by K.  If it exists, remove it and add
    00041     // its label K to the series we wanted to create.
    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   | One Epsilon Closure for weighted automaton |
    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     // Computation of the list of transitions which follow 'eps' This
    00078     // list has to be computed before creating any new transition.
    00079     // Otherwise, if add_to_transition() deletes a transition, it
    00080     // makes the delta_iterator invalid.
    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     // Creation of the new transitions.
    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     // Handling final functions.
    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     // Computation of the list of transitions which precede 'eps'.
    00123     // This list has to be coumputed before creating any new
    00124     // transition.  Otherwise, if add_to_transition deletes a
    00125     // transition, it makes the delta_iterator invalid.
    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     // Creation of the new transitions.
    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     // Handling initial functions.
    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 } // vcsn
    00186
    00187 #endif // ! VCSN_ALGORITHMS_ONE_EPS_CLOSURE_HXX