dfa.hpp
Go to the documentation of this file.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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <sstream>
00039
00040 namespace Gecode {
00041
00046 class DFA::DFAI : public SharedHandle::Object {
00047 public:
00049 int n_states;
00051 unsigned int n_symbols;
00053 int n_trans;
00055 unsigned int max_degree;
00057 int final_fst;
00059 int final_lst;
00061 Transition* trans;
00063 class HashEntry {
00064 public:
00065 int symbol;
00066 const Transition* fst;
00067 const Transition* lst;
00068 };
00070 HashEntry* table;
00072 int n_log;
00074 GECODE_INT_EXPORT void fill(void);
00076 DFAI(int nt);
00078 GECODE_INT_EXPORT DFAI(void);
00080 virtual ~DFAI(void);
00082 GECODE_INT_EXPORT virtual SharedHandle::Object* copy(void) const;
00083 };
00084
00085 forceinline
00086 DFA::DFAI::DFAI(int nt)
00087 : trans(nt == 0 ? NULL : heap.alloc<Transition>(nt)) {}
00088
00089 forceinline
00090 DFA::DFAI::~DFAI(void) {
00091 if (n_trans > 0)
00092 heap.rfree(trans);
00093 heap.rfree(table);
00094 }
00095
00096 forceinline
00097 DFA::DFA(void) {}
00098
00099
00100 forceinline
00101 DFA::DFA(const DFA& d)
00102 : SharedHandle(d) {}
00103
00104 forceinline int
00105 DFA::n_states(void) const {
00106 const DFAI* d = static_cast<DFAI*>(object());
00107 return (d == NULL) ? 1 : d->n_states;
00108 }
00109
00110 forceinline unsigned int
00111 DFA::n_symbols(void) const {
00112 const DFAI* d = static_cast<DFAI*>(object());
00113 return (d == NULL) ? 0 : d->n_symbols;
00114 }
00115
00116 forceinline int
00117 DFA::n_transitions(void) const {
00118 const DFAI* d = static_cast<DFAI*>(object());
00119 return (d == NULL) ? 0 : d->n_trans;
00120 }
00121
00122 forceinline unsigned int
00123 DFA::max_degree(void) const {
00124 const DFAI* d = static_cast<DFAI*>(object());
00125 return (d == NULL) ? 0 : d->max_degree;
00126 }
00127
00128 forceinline int
00129 DFA::final_fst(void) const {
00130 const DFAI* d = static_cast<DFAI*>(object());
00131 return (d == NULL) ? 0 : d->final_fst;
00132 }
00133
00134 forceinline int
00135 DFA::final_lst(void) const {
00136 const DFAI* d = static_cast<DFAI*>(object());
00137 return (d == NULL) ? 0 : d->final_lst;
00138 }
00139
00140 forceinline int
00141 DFA::symbol_min(void) const {
00142 const DFAI* d = static_cast<DFAI*>(object());
00143 return ((d != NULL) && (d->n_trans > 0)) ?
00144 d->trans[0].symbol : Int::Limits::min;
00145 }
00146
00147 forceinline int
00148 DFA::symbol_max(void) const {
00149 const DFAI* d = static_cast<DFAI*>(object());
00150 return ((d != NULL) && (d->n_trans > 0)) ?
00151 d->trans[d->n_trans-1].symbol : Int::Limits::max;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160 forceinline
00161 DFA::Transition::Transition(void) {}
00162
00163 forceinline
00164 DFA::Transition::Transition(int i_state0, int symbol0, int o_state0)
00165 : i_state(i_state0), symbol(symbol0), o_state(o_state0) {}
00166
00167
00168
00169
00170
00171
00172 forceinline
00173 DFA::Transitions::Transitions(const DFA& d) {
00174 const DFAI* o = static_cast<DFAI*>(d.object());
00175 if (o != NULL) {
00176 c_trans = &o->trans[0];
00177 e_trans = c_trans+o->n_trans;
00178 } else {
00179 c_trans = e_trans = NULL;
00180 }
00181 }
00182
00183 forceinline
00184 DFA::Transitions::Transitions(const DFA& d, int n) {
00185 const DFAI* o = static_cast<DFAI*>(d.object());
00186 if (o != NULL) {
00187 int mask = (1<<o->n_log)-1;
00188 int p = n & mask;
00189 while ((o->table[p].fst != NULL) && (o->table[p].symbol != n))
00190 p = (p+1) & mask;
00191 c_trans = o->table[p].fst;
00192 e_trans = o->table[p].lst;
00193 } else {
00194 c_trans = e_trans = NULL;
00195 }
00196 }
00197
00198 forceinline bool
00199 DFA::Transitions::operator ()(void) const {
00200 return c_trans < e_trans;
00201 }
00202
00203 forceinline void
00204 DFA::Transitions::operator ++(void) {
00205 c_trans++;
00206 }
00207
00208 forceinline int
00209 DFA::Transitions::i_state(void) const {
00210 return c_trans->i_state;
00211 }
00212
00213 forceinline int
00214 DFA::Transitions::symbol(void) const {
00215 return c_trans->symbol;
00216 }
00217
00218 forceinline int
00219 DFA::Transitions::o_state(void) const {
00220 return c_trans->o_state;
00221 }
00222
00223
00224
00225
00226
00227
00228 forceinline
00229 DFA::Symbols::Symbols(const DFA& d) {
00230 const DFAI* o = static_cast<DFAI*>(d.object());
00231 if (o != NULL) {
00232 c_trans = &o->trans[0];
00233 e_trans = c_trans+o->n_trans;
00234 } else {
00235 c_trans = e_trans = NULL;
00236 }
00237 }
00238
00239 forceinline bool
00240 DFA::Symbols::operator ()(void) const {
00241 return c_trans < e_trans;
00242 }
00243
00244 forceinline void
00245 DFA::Symbols::operator ++(void) {
00246 int s = c_trans->symbol;
00247 do {
00248 c_trans++;
00249 } while ((c_trans < e_trans) && (s == c_trans->symbol));
00250 }
00251
00252 forceinline int
00253 DFA::Symbols::val(void) const {
00254 return c_trans->symbol;
00255 }
00256
00257
00258 template<class Char, class Traits>
00259 std::basic_ostream<Char,Traits>&
00260 operator <<(std::basic_ostream<Char,Traits>& os, const DFA& d) {
00261 std::basic_ostringstream<Char,Traits> st;
00262 st.copyfmt(os); st.width(0);
00263 st << "Start state: 0" << std::endl
00264 << "States: 0..." << d.n_states()-1 << std::endl
00265 << "Transitions:";
00266 for (int s = 0; s < static_cast<int>(d.n_states()); s++) {
00267 DFA::Transitions t(d);
00268 int n = 0;
00269 while (t()) {
00270 if (t.i_state() == s) {
00271 if ((n % 4) == 0)
00272 st << std::endl << "\t";
00273 st << "[" << t.i_state() << "]"
00274 << "- " << t.symbol() << " >"
00275 << "[" << t.o_state() << "] ";
00276 ++n;
00277 }
00278 ++t;
00279 }
00280 }
00281 st << std::endl << "Final states: "
00282 << std::endl
00283 << "\t[" << d.final_fst() << "] ... ["
00284 << d.final_lst()-1 << "]"
00285 << std::endl;
00286 return os << st.str();
00287 }
00288
00289 }
00290
00291
00292
00293