dfa_bin.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 #ifndef ASTL_DFA_BIN_H
00023 #define ASTL_DFA_BIN_H
00024 
00025 
00026 #include <dfa_base.h>
00027 #include <vector>
00028 #include <algorithm>    // lower_bound()
00029 #include <utility>      // pair<>
00030 #include <functional>
00031 
00032 namespace astl {
00033 
00055 template <class Sigma_ = plain, 
00056           class Tag_   = empty_tag>
00057 class DFA_bin 
00058   : public DFA_base<Sigma_, Tag_, 
00059                     vector<pair<typename Sigma_::char_type, unsigned int> > >
00060 {
00061 public:
00062   typedef DFA_base<Sigma_, Tag_, vector<pair<typename Sigma_::char_type, 
00063                                              unsigned int> > > super;
00064   typedef DFA_bin                    self;
00065   typedef Sigma_                     char_traits;
00066   typedef Tag_                       tag_type;
00067   typedef typename Sigma_::char_type char_type;
00068   typedef unsigned int               state_type;
00069   using super::null_state;
00070   
00071   // Backward compatibility
00072   typedef char_traits Sigma;
00073   typedef char_type   Alphabet;
00074   typedef tag_type    Tag;
00075   typedef state_type  State;
00076 
00077 protected:
00078   typedef vector<pair<typename Sigma_::char_type, 
00079                       unsigned int> > transition_container;
00080   mutable pair<char_type, unsigned int> p;  // optimization
00081         
00082 public:
00083   class edges_type
00084   {
00085     friend class DFA_bin;
00086   protected:
00087     const transition_container *container;
00088 
00089   public:
00090     typedef char_type                 key_type;
00091     typedef state_type                data_type;
00092     typedef pair<key_type, data_type> value_type;
00093     typedef value_type*               pointer;
00094     typedef const value_type*         const_pointer;
00095     typedef value_type&               reference;
00096     typedef const value_type&         const_reference;
00097     typedef unsigned int              size_type;
00098     typedef int                       difference_type;
00099 
00100     struct key_compare : public binary_function<key_type, key_type, bool>
00101     {
00102       bool operator () (const key_type &x, const key_type &y) const {
00103         return char_traits::lt(x, y);
00104       }
00105     }; 
00106     
00107     struct value_compare : public binary_function<value_type, value_type, bool>
00108     {
00109       bool operator () (const value_type &x, const value_type &y) const {
00110         return self::char_traits::lt(x.first, y.first);
00111       }
00112     }; 
00113 
00114     typedef typename transition_container::const_iterator         
00115     const_iterator ;
00116     typedef typename transition_container::const_reverse_iterator 
00117     const_reverse_iterator ;
00118 
00119     // allocation/deallocation:
00120     edges_type(const transition_container *c = NULL)
00121       : container(c) 
00122     { }
00123     
00124     const_iterator begin() const { 
00125       return container->begin(); 
00126     }
00127     const_iterator end() const { 
00128       return container->end(); 
00129     }
00130 
00131     const_reverse_iterator rbegin() const { 
00132       return container->rbegin(); 
00133     }
00134     const_reverse_iterator rend() const { 
00135       return container->rend(); 
00136     }
00137 
00138     bool empty() const { 
00139       return container->empty(); 
00140     }
00141 
00142     size_type size() const { 
00143       return container->size(); 
00144     }
00145 
00146     size_type max_size() const { 
00147       return container->max_size(); 
00148     }
00149     
00150     // map operations:
00151     key_compare key_comp() const {
00152       return key_compare();
00153     }
00154 
00155     value_compare value_comp() const {
00156       return value_compare();
00157     }
00158 
00159     const_iterator find(const key_type& x) const { 
00160       typename transition_container::const_iterator i = 
00161         std::lower_bound(container->begin(), container->end(), 
00162                          make_pair(x, 0), value_compare());
00163 
00164       if (i == container->end() || (*i).first != x)
00165         return container->end();
00166       else
00167         return i;
00168     }
00169 
00170     size_type count(const key_type& x) const { 
00171       return find(x) == end() ? 0 : 1;
00172     }
00173 
00174     const_iterator lower_bound(const key_type& x) const {
00175       return std::lower_bound(container->begin(), container->end(), 
00176                               make_pair(x, 0), value_compare()); 
00177     }
00178 
00179     const_iterator upper_bound(const key_type& x) const { 
00180       return std::upper_bound(container->begin(), container->end(), 
00181                               make_pair(x, 0), value_compare());
00182     }
00183 
00184     pair<const_iterator, const_iterator> equal_range(const key_type& x) const {
00185       return std::equal_range(container->begin(), container->end(),
00186                               make_pair(x, 0), value_compare());
00187     }
00188     
00189     friend bool operator == (const edges_type& x, const edges_type& y) {
00190       return x.container == y.container || *x.container == *y.container;
00191     }
00192   };
00193 
00194   typedef edges_type Edges;
00195 
00196   void set_trans(state_type s, const char_type &a, state_type aim)
00197   {
00198     p.first = a;
00199     p.second = aim;
00200     Q[s]->edges().insert(lower_bound(Q[s]->edges().begin(), 
00201                                      Q[s]->edges().end(), p, 
00202                                      typename edges_type::value_compare()), p);
00203     ++trans_count_;
00204   }
00205 
00206   void del_trans(state_type s, const char_type &a)
00207   {
00208     p.first = a;
00209     Q[s]->edges().erase(lower_bound(Q[s]->edges().begin(), 
00210                                     Q[s]->edges().end(), p, 
00211                                     typename edges_type::value_compare()));
00212     --trans_count_;
00213   }
00214 
00215   void change_trans(state_type s, const char_type &a, state_type new_aim) {
00216     p.first = a;
00217     (*lower_bound(Q[s]->edges().begin(), Q[s]->edges().end(), 
00218                   p, typename edges_type::value_compare())).second = new_aim;
00219   }
00220 
00221   state_type delta1(state_type s, const char_type &a) const
00222   {
00223     p.first = a;
00224     typename transition_container::const_iterator i = 
00225       lower_bound(Q[s]->edges().begin(), Q[s]->edges().end(), 
00226                   p, typename edges_type::value_compare());
00227 
00228     return (i == Q[s]->edges().end() || 
00229             !((*i).first == a)) ? null_state : (*i).second;
00230   }
00231 
00232   edges_type delta2(state_type s) const {
00233     return edges_type(&Q[s]->edges()); 
00234   }
00235 
00236   DFA_bin(unsigned long n = 0)
00237     : super(n)
00238   {}
00239 
00240 protected:
00241   using super::Q;
00242   using super::trans_count_;
00243 };
00244 
00245 } // namespace astl
00246 
00247 #endif
00248 

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