dfa_mtf.h

00001 /*
00002  * ASTL - the Automaton Standard Template Library.
00003  * C++ generic components for Finite State Automata handling.
00004  * Copyright (C) 2000-2003 Vincent Le Maout (vincent.lemaout@chello.fr).
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  * 
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 // Descrition:  
00023 //   ASTL 2.0 Determinisic Finite Automaton Class Template DFA_mtf
00024 //   Representation by arrays with move-to-front method                 
00025 
00026 #ifndef ASTL_DFA_MTF_H
00027 #define ASTL_DFA_MTF_H
00028 
00029 
00030 #include <dfa_base.h>
00031 #include <algorithm>  // find_if
00032 #include <list>
00033 
00034 #if (__GNUG__ && __GNUG__ > 2)
00035 using namespace __gnu_cxx;
00036 #endif
00037 
00038 namespace astl {
00039 
00040 template <class Sigma_ = plain,
00041           class Tag_   = empty_tag>
00042 class DFA_mtf 
00043   : public DFA_base<Sigma_, Tag_, 
00044                     list<pair<typename Sigma_::char_type, unsigned int> > >
00045 {
00046 protected:
00047   typedef list<pair<typename Sigma_::char_type, unsigned int> > 
00048   transition_container;
00049         
00050 public:
00051   typedef DFA_base<Sigma_, Tag_, list<pair<typename Sigma_::char_type, 
00052                                            unsigned int> > > super;
00053   typedef typename super::char_traits     char_traits;
00054   typedef Tag_                            tag_type;
00055   typedef typename char_traits::char_type char_type;
00056   typedef unsigned int                    state_type;
00057   using super::null_state;
00058 
00059   
00060   // Backward compatibility
00061   typedef char_traits Sigma;
00062   typedef char_type   Alphabet;
00063   typedef tag_type    Tag;
00064   typedef state_type  State;
00065 
00066   class edges_type
00067   {
00068     friend class DFA_mtf;
00069   protected:
00070     const transition_container *container;
00071 
00072   public:
00073     typedef char_type                 key_type;
00074     typedef state_type                data_type;
00075     typedef pair<key_type, data_type> value_type;
00076     typedef value_type*               pointer;
00077     typedef const value_type*         const_pointer;
00078     typedef value_type&               reference;
00079     typedef const value_type&         const_reference;
00080     typedef unsigned int              size_type;
00081     typedef int                       difference_type;
00082     
00083     struct key_compare : public binary_function<key_type, key_type, bool>
00084     {
00085       bool operator () (const key_type &x, const key_type &y) const {
00086         return char_traits::eq(x, y);
00087       }
00088     }; 
00089 
00090     struct value_compare : public binary_function<value_type, value_type, bool>
00091     {
00092       bool operator () (const value_type& x, const value_type& y) const {
00093         return key_compare()(x.first, y.first);
00094       }
00095     };
00096     
00097     typedef typename transition_container::const_iterator         
00098     const_iterator;
00099     typedef typename transition_container::const_reverse_iterator 
00100     const_reverse_iterator;
00101 
00102   protected:
00103     edges_type(const transition_container *c = NULL)
00104       : container(c) { }
00105     
00106   public:
00107     edges_type(const edges_type& x) 
00108       : container(x.container) { }
00109     
00110     key_compare key_comp() const { 
00111       return key_compare();
00112     }
00113 
00114     value_compare value_comp() const { 
00115       return value_compare();
00116     }
00117 
00118     const_iterator begin() const { 
00119       return (container->begin()); 
00120     }
00121 
00122     const_iterator end() const { 
00123       return (container->end()); 
00124     }
00125 
00126     const_reverse_iterator rbegin() const { 
00127       return (container->rbegin()); 
00128     }
00129 
00130     const_reverse_iterator rend() const { 
00131       return (container->rend()); 
00132     }
00133 
00134     bool empty() const {    
00135       return (container->empty()); 
00136     }
00137 
00138     size_type size() const {
00139       return (container->size()); // warn: std::list::size() allowed linear time
00140      }
00141 
00142     size_type max_size() const { 
00143       return (container->max_size()); 
00144     }
00145     
00146     const_iterator find(const key_type& x) const { 
00147       return find_if(container->begin(), container->end(), 
00148                      compose1(bind2nd(key_compare(), x), 
00149                               select1st<value_type>()));
00150     }
00151 
00152     size_type count(const key_type& x) const { 
00153       return find(x) == end() ? 0 : 1; 
00154     }
00155 
00156     const_iterator lower_bound(const key_type& x) const { 
00157       return find(x);
00158     }
00159 
00160     const_iterator upper_bound(const key_type& x) const { 
00161       const_iterator result = find(x);
00162       return result == end() ? result : ++result;
00163     }
00164 
00165     pair<const_iterator, const_iterator> equal_range(const key_type& x) const {
00166       const_iterator i = find(x);
00167       return i == end() ? make_pair(i, i) : make_pair(i, ++i);
00168     }
00169     
00170     friend bool operator==(const edges_type& x, const edges_type& y) {
00171       return x.container == y.container || *x.container == *y.container;
00172     }
00173   };
00174 
00175   void set_trans(state_type s, const char_type &a, state_type aim)
00176   {
00177     Q[s]->edges().push_back(make_pair(a, aim));
00178     ++trans_count_;
00179   }
00180 
00181   void del_trans(state_type s, const char_type &a)
00182   {
00183     Q[s]->edges().erase(find_if(Q[s]->edges().begin(), Q[s]->edges().end(), 
00184                                 compose1(bind2nd(typename DFA_mtf<Sigma_,Tag_>::edges_type::key_compare(), a), 
00185                                          select1st<pair<char_type, state_type> >())));
00186     --trans_count_;
00187   }
00188 
00189   void change_trans(state_type s, const char_type &a, state_type new_aim) {
00190     (*find_if(Q[s]->edges().begin(), Q[s]->edges().end(), 
00191               compose1(bind2nd(typename DFA_mtf<Sigma_,Tag_>::edges_type::key_compare(), a), 
00192                        select1st<pair<char_type, state_type> >()))).second = new_aim;
00193   }
00194 
00195   state_type delta1(state_type s, const char_type &a) const
00196   {
00197     transition_container &edges = Q[s]->edges();
00198     typename transition_container::iterator i = 
00199       find_if(edges.begin(), edges.end(), 
00200               compose1(bind2nd(typename DFA_mtf<Sigma_,Tag_>::edges_type::key_compare(), a), 
00201                        select1st<pair<char_type, state_type> >()));
00202     if (i == edges.end()) return null_state;
00203     else {
00204       edges.push_front(*i);
00205       edges.erase(i);
00206       return (*edges.begin()).second;
00207     }
00208   }
00209 
00210   edges_type delta2(state_type s) const {
00211     return edges_type(&Q[s]->edges());
00212   }
00213 
00214   DFA_mtf(unsigned long n = 0)
00215     : super(n)
00216   { }
00217 
00218 protected:
00219   using super::Q;
00220   using super::trans_count_;
00221 };
00222 
00223 } // namespace astl
00224 
00225 #endif // ASTL_DFA_MTF_H
00226 
00227 
00228 
00229 

Generated on Sun Mar 8 02:41:33 2009 for ASTL by  doxygen 1.5.7.1