eval.hxx

00001 // eval.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 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_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/tools/usual_macros.hh>
00024 # include <algorithm>
00025 # include <vector>
00026 
00027 namespace vcsn {
00028 
00029   /*-----.
00030   | Eval |
00031   `-----*/
00032   // precondition : the automaton is realtime
00033   //
00034   // author: Yann Regis-Gianas.
00035   template <typename A, typename auto_t,
00036             typename Selt, typename input_t>
00037   void
00038   do_eval(const AutomataBase<A>&,
00039           const auto_t&     a,
00040           const input_t&    word,
00041           Selt&             result,
00042           bool&             b_result)
00043   {
00044     AUTOMATON_TYPES(auto_t);
00045     // FIXME: for the moment, we use large vectors because the set of hstate_t
00046     // FIXME: can be sparsed. We wanted to be as general as possible.
00047     // FIXME: Variants of eval will be available soon of course.
00048 
00049     hstate_t max_hstate_t = 0;
00050     for_each_state(i, a)
00051       max_hstate_t = std::max(*i, max_hstate_t);
00052 
00053     std::vector<semiring_elt_t> v1(max_hstate_t + 1,
00054                                    semiring_elt_t (a.series().semiring()));
00055     std::vector<bool>           v1_b(max_hstate_t + 1, false);
00056     std::vector<semiring_elt_t> v2(max_hstate_t + 1,
00057                                    semiring_elt_t (a.series().semiring()));
00058     std::vector<bool>           v2_b(max_hstate_t + 1, false);
00059     std::list<htransition_t>            delta_ret;
00060     const typename semiring_elt_t::set_t &semiring = a.series().semiring();
00061     semiring_elt_t zero =
00062       semiring.zero(SELECT(typename semiring_elt_t::value_t));
00063     monoid_elt_t empty(a.series().monoid());
00064 
00065     /*-------------------.
00066     | Initialize the set |
00067     `-------------------*/
00068     std::fill(v1.begin(), v1.end(), zero);
00069 
00070     /*--------.
00071     | Initial |
00072     `--------*/
00073     // FIXME: here we assume that there is only weight in the initial app.
00074     for_each_initial_state(i, a)
00075     {
00076       v1[*i] = a.get_initial(*i).get(empty);
00077       v1_b[*i] = true;
00078     }
00079 
00080     /*------------.
00081     | Computation |
00082     `------------*/
00083     for_all_const_(input_t, e, word)
00084     {
00085       std::fill(v2.begin(), v2.end(), zero);
00086       std::fill(v2_b.begin(), v2_b.end(), false);
00087       for (unsigned i = 0; i < v1.size(); ++i)
00088         if (v1_b[i])
00089         {
00090           // FIXME : use the other version of delta to be more efficient !
00091           delta_ret.clear();
00092           a.letter_deltac(delta_ret, i, *e, delta_kind::transitions());
00093           for_all_const_(std::list<htransition_t>, l, delta_ret)
00094           {
00095             v2[a.dst_of(*l)] += v1[i] *
00096               a.series_of(*l).get(monoid_elt_t(a.structure().series().monoid(), *e));
00097             v2_b[a.dst_of(*l)] = true;
00098           }
00099         }
00100       std::swap(v1, v2);
00101       std::swap(v1_b, v2_b);
00102     }
00103 
00104     /*-----------------.
00105     | Final and Result |
00106     `-----------------*/
00107     result = zero;
00108     b_result = false;
00109     for (unsigned i = 0; i < v1.size(); ++i)
00110       if (v1_b[i])
00111       {
00112         result += v1[i] * a.get_final(i).get(empty);
00113         if (a.is_final(i))
00114           b_result = true;
00115       }
00116   }
00117 
00118   /*---------.
00119   | Wrappers |
00120   `---------*/
00121   template<typename A, typename T, typename W>
00122   typename Element<A, T>::semiring_elt_t
00123   eval(const Element<A, T>& a, const W& word)
00124   {
00125     typename Element<A, T>::semiring_elt_t ret(a.structure().series().semiring());
00126     bool                                   b_ret;
00127 
00128     do_eval(a.structure(), a, word, ret, b_ret);
00129     return ret;
00130   }
00131 
00132   template<typename A, typename T, typename W>
00133   typename Element<A, T>::semiring_elt_t
00134   eval(const Element<A, T>& a, const W& word, bool& b_ret)
00135   {
00136     typename Element<A, T>::semiring_elt_t ret(a.structure().series().semiring());
00137 
00138     do_eval(a.structure(), a, word, ret, b_ret);
00139     return ret;
00140   }
00141 
00142 } // vcsn
00143 
00144 #endif // ! VCSN_ALGORITHMS_EVAL_HXX

Generated on Fri Jul 28 12:18:31 2006 for Vaucanson by  doxygen 1.4.6