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 "gecode/int.hh"
00039
00040 namespace Gecode { namespace Int { namespace Extensional {
00041
00045 class TransByI_State {
00046 public:
00047 forceinline bool
00048 operator()(const DFA::Transition& x, const DFA::Transition& y) {
00049 return x.i_state < y.i_state;
00050 }
00051 forceinline static void
00052 sort(DFA::Transition t[], int n) {
00053 TransByI_State tbis;
00054 Support::quicksort<DFA::Transition,TransByI_State>(t,n,tbis);
00055 }
00056 };
00057
00061 class TransBySymbol {
00062 public:
00063 forceinline bool
00064 operator()(const DFA::Transition& x, const DFA::Transition& y) {
00065 return x.symbol < y.symbol;
00066 }
00067 forceinline static void
00068 sort(DFA::Transition t[], int n) {
00069 TransBySymbol tbs;
00070 Support::quicksort<DFA::Transition,TransBySymbol>(t,n,tbs);
00071 }
00072 };
00073
00077 class TransBySymbolI_State {
00078 public:
00079 forceinline bool
00080 operator()(const DFA::Transition& x, const DFA::Transition& y) {
00081 return ((x.symbol < y.symbol) ||
00082 ((x.symbol == y.symbol) && (x.i_state < y.i_state)));
00083 }
00084 forceinline static void
00085 sort(DFA::Transition t[], int n) {
00086 TransBySymbolI_State tbsi;
00087 Support::quicksort<DFA::Transition,TransBySymbolI_State>(t,n,tbsi);
00088 }
00089 };
00090
00094 class TransByO_State {
00095 public:
00096 forceinline bool
00097 operator()(const DFA::Transition& x, const DFA::Transition& y) {
00098 return x.o_state < y.o_state;
00099 }
00100 forceinline static void
00101 sort(DFA::Transition t[], int n) {
00102 TransByO_State tbos;
00103 Support::quicksort<DFA::Transition,TransByO_State>(t,n,tbos);
00104 }
00105 };
00106
00107
00111 class StateGroup {
00112 public:
00113 int state;
00114 int group;
00115 };
00116
00120 class StateGroupByGroup {
00121 public:
00122 forceinline bool
00123 operator()(const StateGroup& x, const StateGroup& y) {
00124 return ((x.group < y.group) ||
00125 ((x.group == y.group) && (x.state < y.state)));
00126 }
00127 static void
00128 sort(StateGroup sg[], int n) {
00129 StateGroupByGroup o;
00130 Support::quicksort<StateGroup,StateGroupByGroup>(sg,n,o);
00131 }
00132 };
00133
00137 class GroupStates {
00138 public:
00139 StateGroup* fst;
00140 StateGroup* lst;
00141 };
00142
00144 enum StateInfo {
00145 SI_NONE = 0,
00146 SI_FROM_START = 1,
00147 SI_TO_FINAL = 2,
00148 SI_FINAL = 4
00149 };
00150
00151 }}}
00152
00153 namespace Gecode {
00154
00155 DFA::DFA(int start, Transition t_spec[], int f_spec[], bool minimize) {
00156 using namespace Int;
00157 using namespace Extensional;
00158
00159 int n_states = start;
00160 int n_trans = 0;
00161 for (Transition* t = &t_spec[0]; t->i_state >= 0; t++) {
00162 n_states = std::max(n_states,t->i_state);
00163 n_states = std::max(n_states,t->o_state);
00164 n_trans++;
00165 }
00166 for (int* f = &f_spec[0]; *f >= 0; f++)
00167 n_states = std::max(n_states,*f);
00168 n_states++;
00169
00170
00171 GECODE_AUTOARRAY(Transition, trans, n_trans);
00172 for (int i = n_trans; i--; )
00173 trans[i] = t_spec[i];
00174
00175 GECODE_AUTOARRAY(int, final, n_states+1);
00176 GECODE_AUTOARRAY(bool, is_final, n_states+1);
00177 int n_finals = 0;
00178 for (int i = n_states+1; i--; )
00179 is_final[i] = false;
00180 for (int* f = &f_spec[0]; *f != -1; f++) {
00181 is_final[*f] = true;
00182 final[n_finals++] = *f;
00183 }
00184
00185 if (minimize) {
00186
00187 TransBySymbolI_State::sort(trans, n_trans);
00188 GECODE_AUTOARRAY(Transition*, idx, n_trans+1);
00189
00190 int n_symbols = 0;
00191 {
00192 int j = 0;
00193 while (j < n_trans) {
00194 idx[n_symbols++] = &trans[j];
00195 int s = trans[j].symbol;
00196 while ((j < n_trans) && (s == trans[j].symbol))
00197 j++;
00198 }
00199 idx[n_symbols] = &trans[j];
00200 assert(j == n_trans);
00201 }
00202
00203 GECODE_AUTOARRAY(int, s2g, n_states+1);
00204 GECODE_AUTOARRAY(StateGroup, part, n_states+1);
00205 GECODE_AUTOARRAY(GroupStates, g2s, n_states+1);
00206
00207 for (int i = n_states+1; i--; ) {
00208 part[i].state = i;
00209 part[i].group = is_final[i] ? 1 : 0;
00210 s2g[i] = part[i].group;
00211 }
00212
00213
00214
00215
00216
00217 StateGroupByGroup::sort(part,n_states+1);
00218 int n_groups;
00219 if (part[0].group == part[n_states].group) {
00220
00221 g2s[0].fst = &part[0]; g2s[0].lst = &part[n_states+1];
00222 n_groups = 1;
00223 } else {
00224 int i = 0;
00225 assert(part[0].group == 0);
00226 do i++; while (part[i].group == 0);
00227 g2s[0].fst = &part[0]; g2s[0].lst = &part[i];
00228 g2s[1].fst = &part[i]; g2s[1].lst = &part[n_states+1];
00229 n_groups = 2;
00230 }
00231
00232
00233 {
00234 int m_groups;
00235 do {
00236 m_groups = n_groups;
00237
00238 for (int sidx = n_symbols; sidx--; ) {
00239
00240 for (int g = n_groups; g--; ) {
00241
00242 if (g2s[g].lst-g2s[g].fst > 1) {
00243
00244
00245
00246 Transition* t = idx[sidx];
00247 Transition* t_lst = idx[sidx+1];
00248 for (StateGroup* sg = g2s[g].fst; sg<g2s[g].lst; sg++) {
00249 while ((t < t_lst) && (t->i_state < sg->state))
00250 t++;
00251
00252 if ((t < t_lst) && (t->i_state == sg->state))
00253 sg->group = s2g[t->o_state];
00254 else
00255 sg->group = s2g[n_states];
00256 }
00257
00258 StateGroupByGroup::sort(g2s[g].fst,
00259 static_cast<int>(g2s[g].lst-g2s[g].fst));
00260
00261 if (g2s[g].fst->group != (g2s[g].lst-1)->group) {
00262
00263 StateGroup* sg = g2s[g].fst+1;
00264 while ((sg-1)->group == sg->group)
00265 sg++;
00266
00267 StateGroup* lst = g2s[g].lst;
00268 g2s[g].lst = sg;
00269 while (sg < lst) {
00270 s2g[sg->state] = n_groups;
00271 g2s[n_groups].fst = sg++;
00272 while ((sg < lst) && ((sg-1)->group == sg->group)) {
00273 s2g[sg->state] = n_groups; sg++;
00274 }
00275 g2s[n_groups++].lst = sg;
00276 }
00277 }
00278 }
00279 }
00280 }
00281 } while (n_groups != m_groups);
00282
00283 start = s2g[start];
00284
00285 n_finals = 0;
00286 for (int g = n_groups; g--; )
00287 for (StateGroup* sg = g2s[g].fst; sg < g2s[g].lst; sg++)
00288 if (is_final[sg->state]) {
00289 final[n_finals++] = g;
00290 break;
00291 }
00292
00293 GECODE_AUTOARRAY(int, s2r, n_states+1);
00294 for (int i = n_states+1; i--; )
00295 s2r[i] = -1;
00296 for (int g = n_groups; g--; )
00297 s2r[g2s[g].fst->state] = g;
00298
00299 int j = 0;
00300 for (int i = 0; i<n_trans; i++)
00301 if (s2r[trans[i].i_state] != -1) {
00302 trans[j].i_state = s2g[trans[i].i_state];
00303 trans[j].symbol = trans[i].symbol;
00304 trans[j].o_state = s2g[trans[i].o_state];
00305 j++;
00306 }
00307 n_trans = j;
00308 n_states = n_groups;
00309 }
00310 }
00311
00312
00313 GECODE_AUTOSTACK(int, -1, visit, n_states);
00314 GECODE_AUTOARRAY(int, state, n_states);
00315 for (int i=n_states; i--; )
00316 state[i] = SI_NONE;
00317
00318 {
00319
00320
00321 TransByI_State::sort(trans, n_trans);
00322 GECODE_AUTOARRAY(Transition*, idx, n_states+1);
00323 {
00324 int j = 0;
00325 for (int i=0; i<n_states; i++) {
00326 idx[i] = &trans[j];
00327 while ((j < n_trans) && (i == trans[j].i_state))
00328 j++;
00329 }
00330 idx[n_states] = &trans[j];
00331 assert(j == n_trans);
00332 }
00333
00334 state[start] = SI_FROM_START;
00335 visit.push(start);
00336 while (!visit.empty()) {
00337 int s = visit.pop();
00338 for (Transition* t = idx[s]; t < idx[s+1]; t++)
00339 if (!(state[t->o_state] & SI_FROM_START)) {
00340 state[t->o_state] |= SI_FROM_START;
00341 visit.push(t->o_state);
00342 }
00343 }
00344 }
00345
00346
00347 {
00348
00349
00350 TransByO_State::sort(trans, n_trans);
00351 GECODE_AUTOARRAY(Transition*, idx, n_states+1);
00352 {
00353 int j = 0;
00354 for (int i=0; i<n_states; i++) {
00355 idx[i] = &trans[j];
00356 while ((j < n_trans) && (i == trans[j].o_state))
00357 j++;
00358 }
00359 idx[n_states] = &trans[j];
00360 assert(j == n_trans);
00361 }
00362
00363 for (int i = n_finals; i--; ) {
00364 state[final[i]] |= (SI_TO_FINAL | SI_FINAL);
00365 visit.push(final[i]);
00366 }
00367 while (!visit.empty()) {
00368 int s = visit.pop();
00369 for (Transition* t = idx[s]; t < idx[s+1]; t++)
00370 if (!(state[t->i_state] & SI_TO_FINAL)) {
00371 state[t->i_state] |= SI_TO_FINAL;
00372 visit.push(t->i_state);
00373 }
00374 }
00375 }
00376
00377
00378 GECODE_AUTOARRAY(int, re, n_states);
00379 for (int i = n_states; i--; )
00380 re[i] = -1;
00381
00382
00383 int m_states = 0;
00384
00385 re[start] = m_states++;
00386
00387
00388 for (int i = n_states; i--; )
00389 if ((state[i] == (SI_FINAL | SI_FROM_START | SI_TO_FINAL)) && (re[i] < 0))
00390 re[i] = m_states++;
00391
00392 int final_fst = (state[start] & SI_FINAL) ? 0 : 1;
00393 int final_lst = m_states;
00394
00395
00396
00397 for (int i = n_states; i--; )
00398 if ((state[i] == (SI_FROM_START | SI_TO_FINAL)) && (re[i] < 0))
00399 re[i] = m_states++;
00400
00401
00402 int m_trans = 0;
00403 for (int i = n_trans; i--; )
00404 if ((re[trans[i].i_state] >= 0) && (re[trans[i].o_state] >= 0))
00405 m_trans++;
00406
00407
00408 DFAI* d = new DFAI(m_trans);
00409 d->n_states = m_states;
00410 d->n_trans = m_trans;
00411 d->final_fst = final_fst;
00412 d->final_lst = final_lst;
00413 {
00414 int j = 0;
00415 Transition* r = &d->trans[0];
00416 for (int i = 0; i<n_trans; i++)
00417 if ((re[trans[i].i_state] >= 0) && (re[trans[i].o_state] >= 0)) {
00418 r[j].symbol = trans[i].symbol;
00419 r[j].i_state = re[trans[i].i_state];
00420 r[j].o_state = re[trans[i].o_state];
00421 j++;
00422 }
00423 TransBySymbol::sort(r,m_trans);
00424 }
00425 {
00426
00427 unsigned int n_symbols = 0;
00428 for (int i = 0; i<m_trans; ) {
00429 int s = d->trans[i++].symbol;
00430 n_symbols++;
00431 while ((i<m_trans) && (d->trans[i].symbol == s))
00432 i++;
00433 }
00434 d->n_symbols = n_symbols;
00435 }
00436 d->fill();
00437 object(d);
00438 }
00439
00440 DFA::DFA(Reflection::VarMap& vm, Reflection::Arg* arg) {
00441 if (arg->isSharedReference()) {
00442 DFAI* d =
00443 static_cast<DFAI*>(vm.getSharedObject(arg->toSharedReference()));
00444 object(d);
00445 return;
00446 }
00447
00448 Reflection::IntArrayArg* a = arg->toSharedObject()->toIntArray();
00449
00450
00451
00452 int n_trans = (a->size() - 4) / 3;
00453 DFAI* d = new DFAI(n_trans);
00454 d->n_states = (*a)[0];
00455 d->n_symbols = (*a)[1];
00456 d->final_fst = (*a)[2];
00457 d->final_lst = (*a)[3];
00458 d->n_trans = n_trans;
00459 for (int i=0; i<n_trans; i++) {
00460 d->trans[i].i_state = (*a)[4+3*i+0];
00461 d->trans[i].symbol = (*a)[4+3*i+1];
00462 d->trans[i].o_state = (*a)[4+3*i+2];
00463 }
00464 d->fill();
00465 object(d);
00466 vm.putMasterObject(object());
00467 }
00468
00469 Reflection::Arg*
00470 DFA::spec(Reflection::VarMap& vm) const {
00471 int sharedIndex = vm.getSharedIndex(object());
00472 if (sharedIndex >= 0)
00473 return Reflection::Arg::newSharedReference(sharedIndex);
00474 Reflection::IntArrayArg* a =
00475 Reflection::Arg::newIntArray(static_cast<int>(4+3*n_transitions()));
00476 (*a)[0] = n_states();
00477 (*a)[1] = n_symbols();
00478 (*a)[2] = final_fst();
00479 (*a)[3] = final_lst();
00480 const DFAI* o = static_cast<DFAI*>(object());
00481 for (unsigned int i=0; i<n_transitions(); i++ ) {
00482 (*a)[4+3*i+0] = o->trans[i].i_state;
00483 (*a)[4+3*i+1] = o->trans[i].symbol;
00484 (*a)[4+3*i+2] = o->trans[i].o_state;
00485 }
00486 vm.putMasterObject(object());
00487 return Reflection::Arg::newSharedObject(a);
00488 }
00489
00490 SharedHandle::Object*
00491 DFA::DFAI::copy(void) const {
00492 DFAI* d = new DFAI(n_trans);
00493 d->n_states = n_states;
00494 d->n_symbols = n_symbols;
00495 d->n_trans = n_trans;
00496 d->final_fst = final_fst;
00497 d->final_lst = final_lst;
00498 memcpy(&d->trans[0], &trans[0], sizeof(Transition)*n_trans);
00499 d->fill();
00500 return d;
00501 }
00502
00503 void
00504 DFA::DFAI::fill(void) {
00505
00506 n_log = 1;
00507 while (n_symbols >= static_cast<unsigned int>(1<<n_log))
00508 n_log++;
00509
00510 table = static_cast<HashEntry*>
00511 (Memory::malloc(sizeof(HashEntry)*(1<<n_log)));
00512
00513 for (int i=(1<<n_log); i--; )
00514 table[i].fst = table[i].lst = NULL;
00515 int mask = (1 << n_log) - 1;
00516
00517 for (unsigned int i = 0; i<n_trans; ) {
00518 int s = trans[i].symbol;
00519 Transition* fst = &trans[i];
00520 i++;
00521 while ((i<n_trans) && (trans[i].symbol == s))
00522 i++;
00523 Transition* lst = &trans[i];
00524
00525 int p = s & mask;
00526 while (table[p].fst != NULL)
00527 p = (p+1) & mask;
00528 table[p].symbol = s;
00529 table[p].fst = fst;
00530 table[p].lst = lst;
00531 }
00532 }
00533
00534 }
00535
00536 std::ostream&
00537 operator<<(std::ostream& os, const Gecode::DFA& dfa) {
00538 os << "Start state: 0" << std::endl
00539 << "States: 0..." << dfa.n_states()-1 << std::endl
00540 << "Transitions:";
00541 for (int s = 0; s < static_cast<int>(dfa.n_states()); s++) {
00542 Gecode::DFA::Transitions t(dfa);
00543 int n = 0;
00544 while (t()) {
00545 if (t.i_state() == s) {
00546 if ((n % 4) == 0)
00547 os << std::endl << "\t";
00548 os << "[" << t.i_state() << "]"
00549 << "- " << t.symbol() << " >"
00550 << "[" << t.o_state() << "] ";
00551 ++n;
00552 }
00553 ++t;
00554 }
00555 }
00556 os << std::endl << "Final states: "
00557 << std::endl
00558 << "\t[" << dfa.final_fst() << "] ... ["
00559 << dfa.final_lst()-1 << "]"
00560 << std::endl;
00561 return os;
00562 }
00563
00564
00565