00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "gecode/int.hh"
00023 #include "gecode/support/sort.hh"
00024 #include "gecode/support/static-stack.hh"
00025
00026
00027 namespace Gecode { namespace Int { namespace Regular {
00028
00032 class TransByI_State {
00033 public:
00034 forceinline bool
00035 operator()(const DFA::Transition& x, const DFA::Transition& y) {
00036 return x.i_state < y.i_state;
00037 }
00038 forceinline static void
00039 sort(DFA::Transition t[], int n) {
00040 TransByI_State tbis;
00041 Support::quicksort<DFA::Transition,TransByI_State>(t,n,tbis);
00042 }
00043 };
00044
00048 class TransBySymbol {
00049 public:
00050 forceinline bool
00051 operator()(const DFA::Transition& x, const DFA::Transition& y) {
00052 return x.symbol < y.symbol;
00053 }
00054 forceinline static void
00055 sort(DFA::Transition t[], int n) {
00056 TransBySymbol tbs;
00057 Support::quicksort<DFA::Transition,TransBySymbol>(t,n,tbs);
00058 }
00059 };
00060
00064 class TransBySymbolI_State {
00065 public:
00066 forceinline bool
00067 operator()(const DFA::Transition& x, const DFA::Transition& y) {
00068 return ((x.symbol < y.symbol) ||
00069 (x.symbol == y.symbol) && (x.i_state < y.i_state));
00070 }
00071 forceinline static void
00072 sort(DFA::Transition t[], int n) {
00073 TransBySymbolI_State tbsi;
00074 Support::quicksort<DFA::Transition,TransBySymbolI_State>(t,n,tbsi);
00075 }
00076 };
00077
00081 class TransByO_State {
00082 public:
00083 forceinline bool
00084 operator()(const DFA::Transition& x, const DFA::Transition& y) {
00085 return x.o_state < y.o_state;
00086 }
00087 forceinline static void
00088 sort(DFA::Transition t[], int n) {
00089 TransByO_State tbos;
00090 Support::quicksort<DFA::Transition,TransByO_State>(t,n,tbos);
00091 }
00092 };
00093
00094
00098 class StateGroup {
00099 public:
00100 int state;
00101 int group;
00102 };
00103
00107 class StateGroupByGroup {
00108 public:
00109 forceinline bool
00110 operator()(const StateGroup& x, const StateGroup& y) {
00111 return ((x.group < y.group) ||
00112 (x.group == y.group) && (x.state < y.state));
00113 }
00114 static void
00115 sort(StateGroup sg[], int n) {
00116 StateGroupByGroup o;
00117 Support::quicksort<StateGroup,StateGroupByGroup>(sg,n,o);
00118 }
00119 };
00120
00124 class GroupStates {
00125 public:
00126 StateGroup* fst;
00127 StateGroup* lst;
00128 };
00129
00131 enum StateInfo {
00132 SI_NONE = 0,
00133 SI_FROM_START = 1,
00134 SI_TO_FINAL = 2,
00135 SI_FINAL = 4,
00136 };
00137
00138 }}}
00139
00140 namespace Gecode {
00141
00142 void
00143 DFA::init(int start, Transition t_spec[], int f_spec[], bool minimize) {
00144 using namespace Int;
00145 using namespace Regular;
00146
00147 int n_states = start;
00148 int n_trans = 0;
00149 for (Transition* t = &t_spec[0]; t->i_state >= 0; t++) {
00150 n_states = std::max(n_states,t->i_state);
00151 n_states = std::max(n_states,t->o_state);
00152 n_trans++;
00153 }
00154 for (int* f = &f_spec[0]; *f >= 0; f++)
00155 n_states = std::max(n_states,*f);
00156 n_states++;
00157
00158
00159 GECODE_AUTOARRAY(Transition, trans, n_trans);
00160 for (int i = n_trans; i--; )
00161 trans[i] = t_spec[i];
00162
00163 GECODE_AUTOARRAY(int, final, n_states+1);
00164 GECODE_AUTOARRAY(bool, is_final, n_states+1);
00165 int n_finals = 0;
00166 for (int i = n_states+1; i--; )
00167 is_final[i] = false;
00168 for (int* f = &f_spec[0]; *f != -1; f++) {
00169 is_final[*f] = true;
00170 final[n_finals++] = *f;
00171 }
00172
00173 if (minimize) {
00174
00175 TransBySymbolI_State::sort(trans, n_trans);
00176 GECODE_AUTOARRAY(Transition*, idx, n_trans+1);
00177
00178 int n_symbols = 0;
00179 {
00180 int j = 0;
00181 while (j < n_trans) {
00182 idx[n_symbols++] = &trans[j];
00183 int s = trans[j].symbol;
00184 while ((j < n_trans) && (s == trans[j].symbol))
00185 j++;
00186 }
00187 idx[n_symbols] = &trans[j];
00188 assert(j == n_trans);
00189 }
00190
00191 GECODE_AUTOARRAY(int, s2g, n_states+1);
00192 GECODE_AUTOARRAY(StateGroup, part, n_states+1);
00193 GECODE_AUTOARRAY(GroupStates, g2s, n_states+1);
00194
00195 for (int i = n_states+1; i--; ) {
00196 part[i].state = i;
00197 part[i].group = is_final[i] ? 1 : 0;
00198 s2g[i] = part[i].group;
00199 }
00200
00201
00202
00203
00204
00205 StateGroupByGroup::sort(part,n_states+1);
00206 int n_groups;
00207 if (part[0].group == part[n_states].group) {
00208
00209 g2s[0].fst = &part[0]; g2s[0].lst = &part[n_states+1];
00210 n_groups = 1;
00211 } else {
00212 int i = 0;
00213 assert(part[0].group == 0);
00214 do i++; while (part[i].group == 0);
00215 g2s[0].fst = &part[0]; g2s[0].lst = &part[i];
00216 g2s[1].fst = &part[i]; g2s[1].lst = &part[n_states+1];
00217 n_groups = 2;
00218 }
00219
00220
00221 {
00222 int m_groups;
00223 do {
00224 m_groups = n_groups;
00225
00226 for (int sidx = n_symbols; sidx--; ) {
00227
00228 for (int g = n_groups; g--; ) {
00229
00230 if (g2s[g].lst-g2s[g].fst > 1) {
00231
00232
00233
00234 Transition* t = idx[sidx];
00235 Transition* t_lst = idx[sidx+1];
00236 for (StateGroup* sg = g2s[g].fst; sg<g2s[g].lst; sg++) {
00237 while ((t < t_lst) && (t->i_state < sg->state))
00238 t++;
00239
00240 if ((t < t_lst) && (t->i_state == sg->state))
00241 sg->group = s2g[t->o_state];
00242 else
00243 sg->group = s2g[n_states];
00244 }
00245
00246 StateGroupByGroup::sort(g2s[g].fst,
00247 static_cast<int>(g2s[g].lst-g2s[g].fst));
00248
00249 if (g2s[g].fst->group != (g2s[g].lst-1)->group) {
00250
00251 StateGroup* sg = g2s[g].fst+1;
00252 while ((sg-1)->group == sg->group)
00253 sg++;
00254
00255 StateGroup* lst = g2s[g].lst;
00256 g2s[g].lst = sg;
00257 while (sg < lst) {
00258 s2g[sg->state] = n_groups;
00259 g2s[n_groups].fst = sg++;
00260 while ((sg < lst) && ((sg-1)->group == sg->group)) {
00261 s2g[sg->state] = n_groups; sg++;
00262 }
00263 g2s[n_groups++].lst = sg;
00264 }
00265 }
00266 }
00267 }
00268 }
00269 } while (n_groups != m_groups);
00270
00271 start = s2g[start];
00272
00273 n_finals = 0;
00274 for (int g = n_groups; g--; )
00275 for (StateGroup* sg = g2s[g].fst; sg < g2s[g].lst; sg++)
00276 if (is_final[sg->state]) {
00277 final[n_finals++] = g;
00278 break;
00279 }
00280
00281 GECODE_AUTOARRAY(int, s2r, n_states+1);
00282 for (int i = n_states+1; i--; )
00283 s2r[i] = -1;
00284 for (int g = n_groups; g--; )
00285 s2r[g2s[g].fst->state] = g;
00286
00287 int j = 0;
00288 for (int i = 0; i<n_trans; i++)
00289 if (s2r[trans[i].i_state] != -1) {
00290 trans[j].i_state = s2g[trans[i].i_state];
00291 trans[j].symbol = trans[i].symbol;
00292 trans[j].o_state = s2g[trans[i].o_state];
00293 j++;
00294 }
00295 n_trans = j;
00296 n_states = n_groups;
00297 }
00298 }
00299
00300
00301 Support::StaticStack<int> visit(n_states);
00302 GECODE_AUTOARRAY(int, state, n_states);
00303 for (int i=n_states; i--; )
00304 state[i] = SI_NONE;
00305
00306 {
00307
00308
00309 TransByI_State::sort(trans, n_trans);
00310 GECODE_AUTOARRAY(Transition*, idx, n_states+1);
00311 {
00312 int j = 0;
00313 for (int i=0; i<n_states; i++) {
00314 idx[i] = &trans[j];
00315 while ((j < n_trans) && (i == trans[j].i_state))
00316 j++;
00317 }
00318 idx[n_states] = &trans[j];
00319 assert(j == n_trans);
00320 }
00321
00322 state[start] = SI_FROM_START;
00323 visit.push(start);
00324 while (!visit.empty()) {
00325 int s = visit.pop();
00326 for (Transition* t = idx[s]; t < idx[s+1]; t++)
00327 if (!(state[t->o_state] & SI_FROM_START)) {
00328 state[t->o_state] |= SI_FROM_START;
00329 visit.push(t->o_state);
00330 }
00331 }
00332 }
00333
00334
00335 {
00336
00337
00338 TransByO_State::sort(trans, n_trans);
00339 GECODE_AUTOARRAY(Transition*, idx, n_states+1);
00340 {
00341 int j = 0;
00342 for (int i=0; i<n_states; i++) {
00343 idx[i] = &trans[j];
00344 while ((j < n_trans) && (i == trans[j].o_state))
00345 j++;
00346 }
00347 idx[n_states] = &trans[j];
00348 assert(j == n_trans);
00349 }
00350
00351 for (int i = n_finals; i--; ) {
00352 state[final[i]] |= (SI_TO_FINAL | SI_FINAL);
00353 visit.push(final[i]);
00354 }
00355 while (!visit.empty()) {
00356 int s = visit.pop();
00357 for (Transition* t = idx[s]; t < idx[s+1]; t++)
00358 if (!(state[t->i_state] & SI_TO_FINAL)) {
00359 state[t->i_state] |= SI_TO_FINAL;
00360 visit.push(t->i_state);
00361 }
00362 }
00363 }
00364
00365
00366 GECODE_AUTOARRAY(int, re, n_states);
00367 for (int i = n_states; i--; )
00368 re[i] = -1;
00369
00370
00371 int m_states = 0;
00372
00373 re[start] = m_states++;
00374
00375
00376 for (int i = n_states; i--; )
00377 if ((state[i] == (SI_FINAL | SI_FROM_START | SI_TO_FINAL)) && (re[i] < 0))
00378 re[i] = m_states++;
00379
00380 int final_fst = (state[start] & SI_FINAL) ? 0 : 1;
00381 int final_lst = m_states;
00382
00383
00384
00385 for (int i = n_states; i--; )
00386 if ((state[i] == (SI_FROM_START | SI_TO_FINAL)) && (re[i] < 0))
00387 re[i] = m_states++;
00388
00389
00390 int m_trans = 0;
00391 for (int i = n_trans; i--; )
00392 if ((re[trans[i].i_state] >= 0) && (re[trans[i].o_state] >= 0))
00393 m_trans++;
00394
00395
00396 DFAI* d = reinterpret_cast<DFAI*>
00397 (Memory::malloc(sizeof(DFAI) + sizeof(Transition)*(m_trans-1)));
00398 d->use_cnt = 1;
00399 d->n_states = m_states;
00400 d->n_trans = m_trans;
00401 d->final_fst = final_fst;
00402 d->final_lst = final_lst;
00403 {
00404 int j = 0;
00405 Transition* r = &d->trans[0];
00406 for (int i = 0; i<n_trans; i++)
00407 if ((re[trans[i].i_state] >= 0) && (re[trans[i].o_state] >= 0)) {
00408 r[j].symbol = trans[i].symbol;
00409 r[j].i_state = re[trans[i].i_state];
00410 r[j].o_state = re[trans[i].o_state];
00411 j++;
00412 }
00413 TransBySymbol::sort(r,m_trans);
00414 }
00415 dfai = d;
00416 }
00417
00418 }
00419
00420 std::ostream&
00421 operator<<(std::ostream& os, const Gecode::DFA& dfa) {
00422 os << "Start state: 0" << std::endl
00423 << "States: 0..." << dfa.n_states()-1 << std::endl
00424 << "Transitions:";
00425 for (int s = 0; s < static_cast<int>(dfa.n_states()); s++) {
00426 Gecode::DFA::Transitions t(dfa);
00427 int n = 0;
00428 while (t()) {
00429 if (t.transition()->i_state == s) {
00430 if ((n % 4) == 0)
00431 os << std::endl << "\t";
00432 os << "[" << t.transition()->i_state << "]"
00433 << "- " << t.transition()->symbol << " >"
00434 << "[" << t.transition()->o_state << "] ";
00435 ++n;
00436 }
00437 ++t;
00438 }
00439 }
00440 os << std::endl << "Final states: "
00441 << std::endl
00442 << "\t[" << dfa.final_fst() << "] ... ["
00443 << dfa.final_lst()-1 << "]"
00444 << std::endl;
00445 return os;
00446 }
00447
00448 namespace Gecode {
00449
00450 DFA::DFAI*
00451 DFA::DFAI::copy(void) {
00452 DFAI* d = reinterpret_cast<DFAI*>
00453 (Memory::malloc(sizeof(DFAI) + sizeof(Transition)*(n_trans-1)));
00454 d->use_cnt = 1;
00455 d->n_states = n_states;
00456 d->n_trans = n_trans;
00457 d->final_fst = final_fst;
00458 d->final_lst = final_lst;
00459 memcpy(&d->trans[0], &trans[0], sizeof(Transition)*n_trans);
00460 return d;
00461 }
00462
00463 }
00464
00465
00466