Vaucanson 1.4
|
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, 2006, 2008 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/misc/usual_macros.hh> 00024 # include <algorithm> 00025 # include <vector> 00026 00027 namespace vcsn { 00028 00029 /*-----. 00030 | Eval | 00031 `-----*/ 00032 00033 // precondition : the automaton is realtime 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 // Initialize 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 // Computation 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 for (delta_iterator t(a.value(), a.get_state(i)); ! t.done(); t.next()) 00079 { 00080 monoid_elt_t l_w(a.series_of(*t).structure().monoid(), *l); 00081 if (a.series_of(*t).get(l_w) != a.series().semiring().wzero_) 00082 { 00083 v2[a.dst_of(*t)] += *w * 00084 a.series_of(*t).get(monoid_elt_t(a.structure().series().monoid(), *l)); 00085 } 00086 } 00087 } 00088 ++i; 00089 } 00090 std::swap(v1, v2); 00091 } 00092 00093 // Result 00094 result = zero; 00095 int i = 0; 00096 for_all_const_ (weights, w, v1) 00097 { 00098 if (*w != zero) 00099 result += *w * a.get_final(i).get(empty); 00100 ++i; 00101 } 00102 } 00103 }; 00104 00105 /*----------. 00106 | Wrapper. | 00107 `----------*/ 00108 00109 template<typename A, typename AI, typename W> 00110 typename Element<A, AI>::semiring_elt_t 00111 eval(const Element<A, AI>& a, const W& word) 00112 { 00113 BENCH_TASK_SCOPED("eval"); 00114 typedef Element<A, AI> automaton_t; 00115 AUTOMATON_TYPES(automaton_t); 00116 semiring_elt_t ret(a.structure().series().semiring()); 00117 00118 // Check if the automaton is empty. 00119 if (!is_empty(a)) 00120 { 00121 eval_functor<automaton_t, W, semiring_elt_t> evalf(a.structure(), a); 00122 evalf.execute(word, ret); 00123 } 00124 00125 return ret; 00126 } 00127 00128 } // ! vcsn 00129 00130 #endif // ! VCSN_ALGORITHMS_EVAL_HXX