00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_SEARCH_HXX
00018 # define VCSN_ALGORITHMS_SEARCH_HXX
00019
00020 # include <vaucanson/algorithms/search.hh>
00021
00022 # include <vaucanson/misc/window.hh>
00023 # include <vaucanson/misc/bitset.hh>
00024
00025 # include <vector>
00026
00027 namespace vcsn {
00028
00029 template <class InputIterator, class FoundFunctor, class Series, class T>
00030 void
00031 search(const Element<Automata<Series>, T>& a,
00032 const InputIterator& begin,
00033 const InputIterator& end,
00034 typename Element<Automata<Series>, T>::letter_t eol,
00035 FoundFunctor& f)
00036 {
00037 TIMER_SCOPED("search");
00038 FindBestSearch::search(a, begin, end, eol, f);
00039 }
00040
00041 template <class InputIterator, class FoundFunctor, class Series, class T>
00042 void
00043 FindBestSearch::search(const Element<Automata<Series>, T>& a,
00044 const InputIterator& begin,
00045 const InputIterator& end,
00046 typename Element<Automata<Series>, T>::
00047 letter_t eol,
00048 FoundFunctor& f)
00049 {
00050 WindowedBackSearch::search(a, begin, end, eol, f);
00051 }
00052
00063 template <class Series, class T, class StatesSet>
00064 static
00065 unsigned int
00066 compute_distances(const Element<Automata<Series>, T>& a,
00067 std::vector<StatesSet>& distances)
00068 {
00069 precondition(a.initial().size() > 0);
00070 precondition(a.final().size() > 0);
00071 precondition(distances.size() == 0);
00072
00073
00074 typedef typename vcsn::Element<Automata<Series>, T> automaton_t;
00075 AUTOMATON_TYPES(automaton_t);
00076
00077
00078 StatesSet s_new (a.states().back() + 1);
00079 StatesSet s_old (a.states().back() + 1);
00080 unsigned int i = 0;
00081
00082 s_old.insert(a.initial().begin(), a.initial().end());
00083 for (bool get_out = false; !get_out; ++i)
00084 {
00085 s_new.clear();
00086 distances.push_back(s_old);
00087 if (i > 0)
00088 distances[i].insert(distances[i - 1].begin(),
00089 distances[i - 1].end());
00090 for (typename StatesSet::const_iterator s = s_old.begin();
00091 s != s_old.end();
00092 ++s)
00093 {
00094 if (a.is_final(*s))
00095
00096
00097 get_out = true;
00098 a.deltac(s_new, *s, delta_kind::states());
00099 }
00100 std::swap(s_new, s_old);
00101 }
00102
00103 postcondition(i == distances.size());
00104 return i - 1;
00105 }
00106
00121 template <class InputIterator, class Series, class T, class StatesSet>
00122 static
00123 std::pair<bool, unsigned int>
00124 window_backsearch(const misc::Window<InputIterator,
00125 typename Element<Automata<Series>, T>::letter_t>& w,
00126 const Element<Automata<Series>, T>& a,
00127 const std::vector<StatesSet>& distances)
00128 {
00129 precondition(w.size() > 0);
00130
00131
00132 typedef typename vcsn::Element<Automata<Series>, T> automaton_t;
00133 AUTOMATON_TYPES(automaton_t);
00134 AUTOMATON_FREEMONOID_TYPES(automaton_t);
00135 typedef typename misc::Window<InputIterator, letter_t> window_t;
00136 typedef typename window_t::length_t length_t;
00137 typedef misc::Bitset bitset_t;
00138
00139
00140 bitset_t s_new (a.states().back() + 1);
00141 bitset_t s_old (a.states().back() + 1);
00142 int pos = w.size();
00143 length_t critpos = pos;
00144
00145 s_old.insert(distances[pos].begin(), distances[pos].end());
00146 while ((--pos >= 0) && !s_old.empty())
00147 {
00148 s_new.clear();
00149 for (bitset_t::const_iterator s = s_old.begin(); s != s_old.end(); ++s)
00150 if (distances[pos + 1].find(*s) != distances[pos + 1].end())
00151 {
00152 if (a.is_initial(*s))
00153 critpos = pos + 1;
00154 a.letter_rdeltac(s_new, *s, w[pos], delta_kind::states());
00155 }
00156 std::swap(s_new, s_old);
00157 }
00158 if (pos < 0)
00159 for (bitset_t::const_iterator s = s_old.begin(); s != s_old.end(); ++s)
00160 if (a.is_initial(*s))
00161 return std::make_pair(true, critpos);
00162 return std::make_pair(false, critpos);
00163 }
00164
00166 template <class InputIterator, class FoundFunctor, class Series, class T>
00167 static
00168 InputIterator
00169 confirm_and_report_match(const misc::Window<InputIterator,
00170 typename Element<Automata<Series>, T>::letter_t>& w,
00171 const Element<Automata<Series>, T>& a,
00172 FoundFunctor& f)
00173 {
00174
00175 typedef typename vcsn::Element<Automata<Series>, T> automaton_t;
00176 AUTOMATON_TYPES(automaton_t);
00177 AUTOMATON_FREEMONOID_TYPES(automaton_t);
00178 typedef typename misc::Window<InputIterator, letter_t> window_t;
00179 typedef typename window_t::length_t length_t;
00180 typedef typename window_t::iterator_t iterator_t;
00181 typedef misc::Bitset bitset_t;
00182
00183
00184 bitset_t s_old (a.states().back() + 1);
00185 bitset_t s_new (a.states().back() + 1);
00186 iterator_t pos = w.stream();
00187 iterator_t last = pos;
00188
00189 s_old.insert(a.initial().begin(), a.initial().end());
00190 while (!s_old.empty() && (*pos != w.eol_value()))
00191 {
00192 s_new.clear();
00193 for (bitset_t::const_iterator s = s_old.begin(); s != s_old.end(); ++s)
00194 {
00195 if (a.is_final(*s))
00196 last = pos - 1;
00197 a.letter_deltac(s_new, *s, *pos, delta_kind::states());
00198 }
00199 std::swap(s_old, s_new);
00200 ++pos;
00201 }
00202 for (bitset_t::const_iterator s = s_old.begin(); s != s_old.end(); ++s)
00203 if (a.is_final(*s))
00204 last = pos - 1;
00205 if (last != pos)
00206 return f(w.begin(), w.stream(), last);
00207 else
00208 return w.stream();
00209 }
00210
00213 template <class InputIterator, class FoundFunctor, class Series, class T>
00214 void
00215 WindowedBackSearch::search(const Element<Automata<Series>, T>& a,
00216 const InputIterator& begin,
00217 const InputIterator& end,
00218 typename Element<Automata<Series>, T>::
00219 letter_t eol,
00220 FoundFunctor& f)
00221 {
00222
00223 typedef typename vcsn::Element<Automata<Series>, T> automaton_t;
00224 AUTOMATON_TYPES(automaton_t);
00225 AUTOMATON_FREEMONOID_TYPES(automaton_t);
00226 typedef typename misc::Window<InputIterator, letter_t> window_t;
00227 typedef typename window_t::length_t length_t;
00228 typedef misc::Bitset bitset_t;
00229
00230
00231 std::vector<bitset_t> distances;
00232 length_t wl = compute_distances(a, distances);
00233
00234 if (wl == 0)
00235 WARNING("Search match every position in the stream, ignored.");
00236 else
00237 {
00238 window_t w (begin, end, eol, wl);
00239 InputIterator it;
00240
00241 while (!w.eof())
00242 {
00243 if (w.size() != wl)
00244 w.shift();
00245 else
00246 {
00247 std::pair<bool, length_t> p =
00248 window_backsearch(w, a, distances);
00249 if (p.first &&
00250 (it = confirm_and_report_match(w, a, f)) != w.stream())
00251 w.moveto(it);
00252 else
00253 w.shift(p.second);
00254 }
00255 }
00256 }
00257 }
00258
00259 }
00260
00261 #endif // ! VCSN_ALGORITHMS_SEARCH_HXX