00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 #ifndef VCSN_ALGORITHMS_EVAL_HXX
00018 # define VCSN_ALGORITHMS_EVAL_HXX
00019 
00020 # include <vaucanson/algorithms/eval.hh>
00021 # include <vaucanson/automata/concept/automata_base.hh>
00022 # include <vaucanson/misc/selectors.hh>
00023 # include <vaucanson/misc/usual_macros.hh>
00024 # include <algorithm>
00025 # include <vector>
00026 
00027 namespace vcsn {
00028 
00029   
00030 
00031 
00032 
00033   
00034   template <typename auto_t, typename input_t, typename Selt>
00035   struct eval_functor
00036   {
00037       AUTOMATON_TYPES(auto_t);
00038 
00039       typedef std::vector<semiring_elt_t> weights;
00040 
00041       const auto_t& a;
00042       int max_hstate;
00043 
00044       weights v1, v2;
00045 
00046       typename weights::const_iterator w;
00047       typename input_t::const_iterator l;
00048 
00049       template <typename A>
00050       eval_functor(const AutomataBase<A>&, const auto_t& aut)
00051         : a(aut), max_hstate(a.states().back() + 1),
00052           v1(max_hstate, a.series().semiring().wzero_), v2(max_hstate)
00053       {}
00054 
00055       void execute(const input_t& word, Selt& result)
00056       {
00057         const monoid_elt_t empty = algebra::identity_as<monoid_elt_value_t>::of(a.series().monoid());
00058 
00059         
00060         for_all_const_initial_states(i, a)
00061           v1[*i] = a.get_initial(*i).get(empty);
00062 
00063         const semiring_elt_t zero = a.series().semiring().wzero_;
00064 
00065         
00066         l = word.begin();
00067         for (typename input_t::const_iterator w_end = word.end();
00068              l != w_end; ++l)
00069         {
00070           std::fill(v2.begin(), v2.end(), zero);
00071           int i = 0;
00072           w = v1.begin();
00073           for (typename weights::const_iterator v1_end = v1.end();
00074                w != v1_end; ++w)
00075           {
00076             if (*w != zero)
00077             {
00078               std::list<htransition_t> tr;
00079               a.letter_deltac(tr, i, *l, delta_kind::transitions());
00080               for (typename std::list<htransition_t>::const_iterator t = tr.begin(); t != tr.end(); ++t)
00081               {
00082                 v2[a.dst_of(*t)] += *w *
00083                   a.series_of(*t).get(monoid_elt_t(a.structure().series().monoid(), *l));
00084               }
00085             }
00086             ++i;
00087           }
00088           std::swap(v1, v2);
00089         }
00090 
00091         
00092         result = zero;
00093         int i = 0;
00094         for_all_const_ (weights, w, v1)
00095         {
00096           if (*w != zero)
00097             result += *w * a.get_final(i).get(empty);
00098           ++i;
00099         }
00100       }
00101   };
00102 
00103   
00104 
00105 
00106 
00107   template<typename A, typename AI, typename W>
00108   typename Element<A, AI>::semiring_elt_t
00109   eval(const Element<A, AI>& a, const W& word)
00110   {
00111     TIMER_SCOPED("eval");
00112     typedef Element<A, AI> automaton_t;
00113     AUTOMATON_TYPES(automaton_t);
00114     semiring_elt_t ret(a.structure().series().semiring());
00115 
00116     
00117     if (!is_empty(a))
00118     {
00119       eval_functor<automaton_t, W, semiring_elt_t> evalf(a.structure(), a);
00120       evalf.execute(word, ret);
00121     }
00122 
00123     return ret;
00124   }
00125 
00126 } 
00127 
00128 #endif // ! VCSN_ALGORITHMS_EVAL_HXX