00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef ASTL_DFA_MTF_H
00027 #define ASTL_DFA_MTF_H
00028
00029
00030 #include <dfa_base.h>
00031 #include <algorithm>
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
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());
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 }
00224
00225 #endif // ASTL_DFA_MTF_H
00226
00227
00228
00229