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

# search.hxx

    00001 // search.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 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_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     // Typedefs.
    00074     typedef typename vcsn::Element<Automata<Series>, T> automaton_t;
    00075     AUTOMATON_TYPES(automaton_t);
    00076
    00077     // Code.
    00078     StatesSet           s_new (a.states().max() + 1);
    00079     StatesSet           s_old (a.states().max() + 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               // FIXME: Could be optimized with a return i, but code
    00096               // is easier to read this way.
    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     // Typedefs.
    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     // Code.
    00140     bitset_t    s_new (a.states().max() + 1);
    00141     bitset_t    s_old (a.states().max() + 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     // Typedefs.
    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     // Code.
    00184     bitset_t    s_old (a.states().max() + 1);
    00185     bitset_t    s_new (a.states().max() + 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     // Typedefs.
    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     // Code.
    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 } // vcsn
    00260
    00261 #endif // ! VCSN_ALGORITHMS_SEARCH_HXX