Generated on for Gecode by doxygen 1.15.0
reg.cpp
Go to the documentation of this file.
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.dev>
5 *
6 * Copyright:
7 * Christian Schulte, 2004
8 *
9 * This file is part of Gecode, the generic constraint
10 * development environment:
11 * http://www.gecode.dev
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining
14 * a copy of this software and associated documentation files (the
15 * "Software"), to deal in the Software without restriction, including
16 * without limitation the rights to use, copy, modify, merge, publish,
17 * distribute, sublicense, and/or sell copies of the Software, and to
18 * permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be
22 * included in all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 *
32 */
33
34#include <gecode/minimodel.hh>
35
36namespace Gecode {
37
38 namespace MiniModel {
39
40 class PosSet;
45
46 class NodeInfo;
47 class PosInfo;
48
49 }
50
52 class REG::Exp {
53 public:
55 unsigned int use_cnt;
57 int _n_pos;
67
70 union {
72 int symbol;
74 Exp* kids[2];
76
81 static void inc(Exp* e);
83 static void dec(Exp* e);
85 static int n_pos(Exp* e);
87 void toString(std::ostringstream& os) const;
89 std::string toString(void) const;
90
91 static void* operator new(size_t);
92 static void operator delete(void*);
93 private:
95 void dispose(void);
96 };
97
98
99 /*
100 * Operations on expression nodes
101 *
102 */
103
104
105 forceinline void*
106 REG::Exp::operator new(size_t s) {
107 return heap.ralloc(s);
108 }
109 forceinline void
110 REG::Exp::operator delete(void*) {
111 // Deallocation happens in dispose
112 }
113
114 void
115 REG::Exp::dispose(void) {
116 Region region;
118 todo.push(this);
119 while (!todo.empty()) {
120 Exp* e = todo.pop();
121 switch (e->type) {
122 case ET_OR:
123 case ET_CONC:
124 if ((e->data.kids[1] != nullptr) && (--e->data.kids[1]->use_cnt == 0))
125 todo.push(e->data.kids[1]);
126 // fall through
127 case ET_STAR:
128 if ((e->data.kids[0] != nullptr) && (--e->data.kids[0]->use_cnt == 0))
129 todo.push(e->data.kids[0]);
130 default: ;
131 }
132 heap.rfree(e);
133 }
134 }
135
136 forceinline void
138 if (e != nullptr)
139 e->use_cnt++;
140 }
141 forceinline void
143 if ((e != nullptr) && (--e->use_cnt == 0))
144 e->dispose();
145 }
146
147
148 forceinline int
150 return (e != nullptr) ? e->_n_pos : 0;
151 }
152
153 void
154 REG::Exp::toString(std::ostringstream& os) const {
155 switch (type) {
156 case ET_SYMBOL:
157 os << "[" << data.symbol << "]";
158 return;
159 case ET_STAR:
160 {
161 bool par = ((data.kids[0] != nullptr) &&
162 ((data.kids[0]->type == ET_CONC) ||
163 (data.kids[0]->type == ET_OR)));
164 os << (par ? "*(" : "*");
165 if (data.kids[0]==nullptr) {
166 os << "[]";
167 } else {
168 data.kids[0]->toString(os);
169 }
170 os << (par ? ")" : "");
171 return;
172 }
173 case ET_CONC:
174 {
175 bool par0 = ((data.kids[0] != nullptr) &&
176 (data.kids[0]->type == ET_OR));
177 os << (par0 ? "(" : "");
178 if (data.kids[0]==nullptr) {
179 os << "[]";
180 } else {
181 data.kids[0]->toString(os);
182 }
183 os << (par0 ? ")+" : "+");
184 bool par1 = ((data.kids[1] != nullptr) &&
185 (data.kids[1]->type == ET_OR));
186 os << (par1 ? "(" : "");
187 if (data.kids[1]==nullptr) {
188 os << "[]";
189 } else {
190 data.kids[1]->toString(os);
191 }
192 os << (par1 ? ")" : "");
193 return;
194 }
195 case ET_OR:
196 if (data.kids[0]==nullptr) {
197 os << "[]";
198 } else {
199 data.kids[0]->toString(os);
200 }
201 os << "|";
202 if (data.kids[1]==nullptr) {
203 os << "[]";
204 } else {
205 data.kids[1]->toString(os);
206 }
207 return;
208 default: GECODE_NEVER;
209 }
211 return;
212 }
213
214 std::string
215 REG::Exp::toString(void) const {
216 std::ostringstream os;
217 toString(os);
218 return os.str();
219 }
220
221
222 /*
223 * Regular expressions
224 *
225 */
226
228 REG::REG(Exp* f) : e(f) {}
229
230 REG::REG(void) : e(nullptr) {}
231
232 REG::REG(const REG& r) : e(r.e) {
233 REG::Exp::inc(e);
234 }
235
236 const REG&
237 REG::operator =(const REG& r) {
238 if (&r != this) {
239 REG::Exp::inc(r.e);
240 REG::Exp::dec(e);
241 e = r.e;
242 }
243 return *this;
244 }
245
246 REG::~REG(void) {
247 REG::Exp::dec(e);
248 }
249
250 REG::REG(int s) : e(new Exp) {
251 e->use_cnt = 1;
252 e->_n_pos = 1;
253 e->type = REG::Exp::ET_SYMBOL;
254 e->data.symbol = s;
255 }
256
257 REG::REG(const IntArgs& x) {
258 int n = x.size();
259 if (n < 1)
260 throw MiniModel::TooFewArguments("REG");
261 Region region;
262 Exp** a = region.alloc<Exp*>(n);
263 // Initialize with symbols
264 for (int i=n; i--; ) {
265 a[i] = new Exp();
266 a[i]->use_cnt = 1;
267 a[i]->_n_pos = 1;
268 a[i]->type = REG::Exp::ET_SYMBOL;
269 a[i]->data.symbol = x[i];
270 }
271 // Build a balanced tree of alternative nodes
272 for (int m=n; m>1; ) {
273 if (m & 1) {
274 m -= 1;
275 Exp* e1 = a[m];
276 Exp* e2 = a[0];
277 a[0] = new Exp;
278 a[0]->use_cnt = 1;
279 a[0]->_n_pos = REG::Exp::n_pos(e1) + REG::Exp::n_pos(e2);
280 a[0]->type = REG::Exp::ET_OR;
281 a[0]->data.kids[0] = e1;
282 a[0]->data.kids[1] = e2;
283 } else {
284 m >>= 1;
285 for (int i=0; i<m; i++) {
286 Exp* e1 = a[2*i];
287 Exp* e2 = a[2*i+1];
288 a[i] = new Exp;
289 a[i]->use_cnt = 1;
290 a[i]->_n_pos = REG::Exp::n_pos(e1) + REG::Exp::n_pos(e2);
291 a[i]->type = REG::Exp::ET_OR;
292 a[i]->data.kids[0] = e1;
293 a[i]->data.kids[1] = e2;
294 }
295 }
296 }
297 e = a[0];
298 }
299
300 REG
301 REG::operator |(const REG& r2) {
302 if (e == r2.e)
303 return *this;
304 Exp* f = new Exp();
305 f->use_cnt = 1;
306 f->_n_pos = REG::Exp::n_pos(e) + REG::Exp::n_pos(r2.e);
307 f->type = REG::Exp::ET_OR;
308 f->data.kids[0] = e; REG::Exp::inc(e);
309 f->data.kids[1] = r2.e; REG::Exp::inc(r2.e);
310 REG r(f);
311 return r;
312 }
313
314 REG&
315 REG::operator |=(const REG& r2) {
316 if (e == r2.e)
317 return *this;
318 Exp* f = new Exp();
319 f->use_cnt = 1;
320 f->_n_pos = REG::Exp::n_pos(e) + REG::Exp::n_pos(r2.e);
321 f->type = REG::Exp::ET_OR;
322 f->data.kids[0] = e;
323 f->data.kids[1] = r2.e; REG::Exp::inc(r2.e);
324 e=f;
325 return *this;
326 }
327
328 REG
329 REG::operator +(const REG& r2) {
330 if (e == nullptr) return r2;
331 if (r2.e == nullptr) return *this;
332 Exp* f = new Exp();
333 f->use_cnt = 1;
334 f->_n_pos = REG::Exp::n_pos(e) + REG::Exp::n_pos(r2.e);
335 f->type = REG::Exp::ET_CONC;
336 f->data.kids[0] = e; REG::Exp::inc(e);
337 f->data.kids[1] = r2.e; REG::Exp::inc(r2.e);
338 REG r(f);
339 return r;
340 }
341
342 REG&
343 REG::operator +=(const REG& r2) {
344 if (r2.e == nullptr)
345 return *this;
346 if (e == nullptr) {
347 e=r2.e; REG::Exp::inc(e);
348 } else {
349 Exp* f = new Exp();
350 f->use_cnt = 1;
351 f->_n_pos = REG::Exp::n_pos(e) + REG::Exp::n_pos(r2.e);
352 f->type = REG::Exp::ET_CONC;
353 f->data.kids[0] = e;
354 f->data.kids[1] = r2.e; REG::Exp::inc(r2.e);
355 e=f;
356 }
357 return *this;
358 }
359
360 REG
362 if ((e == nullptr) || (e->type == REG::Exp::ET_STAR))
363 return *this;
364 Exp* f = new Exp();
365 f->use_cnt = 1;
366 f->_n_pos = REG::Exp::n_pos(e);
367 f->type = REG::Exp::ET_STAR;
368 f->data.kids[0] = e; REG::Exp::inc(e);
369 REG r(f);
370 return r;
371 }
372
373 REG
374 REG::operator ()(unsigned int n, unsigned int m) {
375 REG r;
376 if ((n>m) || (m == 0))
377 return r;
378 if (n>0) {
379 unsigned int i = n;
380 REG r0 = *this;
381 while (i>0)
382 if (i & 1) {
383 r = r0+r; i--;
384 } else {
385 r0 = r0+r0; i >>= 1;
386 }
387 }
388 if (m > n) {
389 unsigned int i = m-n;
390 REG s0;
391 s0 = s0 | *this;
392 REG s;
393 while (i>0)
394 if (i & 1) {
395 s = s0+s; i--;
396 } else {
397 s0 = s0+s0; i >>= 1;
398 }
399 r = r + s;
400 }
401 return r;
402 }
403
404 REG
405 REG::operator ()(unsigned int n) {
406 REG r;
407 if (n > 0) {
408 REG r0 = *this;
409 unsigned int i = n;
410 while (i>0)
411 if (i & 1) {
412 r = r0+r; i--;
413 } else {
414 r0 = r0+r0; i >>= 1;
415 }
416 }
417 return r+**this;
418 }
419
420 REG
422 return this->operator ()(1);
423 }
424
425 std::string
426 REG::toString(void) const {
427 if (e==nullptr) {
428 return "[]";
429 }
430 return e->toString();
431 }
432
433 namespace MiniModel {
434
435 /*
436 * Sets of positions
437 *
438 */
439
448
452 class PosSet : public Support::BlockClient<PosSet,Region> {
453 // Maintain sets of positions in inverse order
454 // This makes the check whether the last position is included
455 // more efficient.
456 public:
458
459 PosSet(void);
460 PosSet(int);
461
462 bool in(int) const;
463 static PosSetCmp cmp(PosSet*,PosSet*);
465 };
466
467
471 PosSet::PosSet(int p) : pos(p), next(nullptr) {}
472
473
474 forceinline bool
475 PosSet::in(int p) const {
476 for (const PosSet* ps = this; ps != nullptr; ps = ps->next)
477 if (ps->pos == p) {
478 return true;
479 } else if (ps->pos < p) {
480 return false;
481 }
482 return false;
483 }
484
487 while ((ps1 != nullptr) && (ps2 != nullptr)) {
488 if (ps1 == ps2)
489 return PSC_EQ;
490 if (ps1->pos < ps2->pos)
491 return PSC_LE;
492 if (ps1->pos > ps2->pos)
493 return PSC_GR;
494 ps1 = ps1->next; ps2 = ps2->next;
495 }
496 if (ps1 == ps2)
497 return PSC_EQ;
498 return ps1 == nullptr ? PSC_LE : PSC_GR;
499 }
500
501 PosSet*
503 PosSet* ps;
504 PosSet** p = &ps;
505 while ((ps1 != nullptr) && (ps2 != nullptr)) {
506 if (ps1 == ps2) {
507 *p = ps1; return ps;
508 }
509 PosSet* n = new (psm) PosSet;
510 *p = n; p = &n->next;
511 if (ps1->pos == ps2->pos) {
512 n->pos = ps1->pos;
513 ps1 = ps1->next; ps2 = ps2->next;
514 } else if (ps1->pos > ps2->pos) {
515 n->pos = ps1->pos; ps1 = ps1->next;
516 } else {
517 n->pos = ps2->pos; ps2 = ps2->next;
518 }
519 }
520 *p = (ps1 != nullptr) ? ps1 : ps2;
521 return ps;
522 }
523
524
526 class NodeInfo {
527 public:
531 NodeInfo(bool n=false, PosSet* fp=nullptr, PosSet* lp=nullptr);
532 };
533
535 class ExpInfo {
536 public:
538 bool open;
539 ExpInfo(REG::Exp* e=nullptr);
540 };
541
546 class PosInfo {
547 public:
550 };
551
554 : nullable(n), firstpos(fp), lastpos(lp) {}
555
558 : exp(e), open(true) {}
559
560 }
561
565 int p=0;
566
567 using MiniModel::PosSet;
569 using MiniModel::ExpInfo;
570
571 Region region;
572
575
576 // Start with first expression to be processed
577 todo.push(ExpInfo(this));
578
579 do {
580 if (todo.top().exp == nullptr) {
581 todo.pop();
582 done.push(NodeInfo(true,nullptr,nullptr));
583 } else {
584 switch (todo.top().exp->type) {
585 case ET_SYMBOL:
586 {
587 pi[p].symbol = todo.pop().exp->data.symbol;
588 PosSet* ps = new (psm) PosSet(p++);
589 done.push(NodeInfo(false,ps,ps));
590 }
591 break;
592 case ET_STAR:
593 if (todo.top().open) {
594 // Evaluate subexpression recursively
595 todo.top().open = false;
596 todo.push(todo.top().exp->data.kids[0]);
597 } else {
598 todo.pop();
599 NodeInfo ni = done.pop();
600 for (PosSet* ps = ni.lastpos; ps != nullptr; ps = ps->next)
601 pi[ps->pos].followpos =
602 PosSet::cup(psm,pi[ps->pos].followpos,ni.firstpos);
603 done.push(NodeInfo(true,ni.firstpos,ni.lastpos));
604 }
605 break;
606 case ET_CONC:
607 if (todo.top().open) {
608 // Evaluate subexpressions recursively
609 todo.top().open = false;
610 REG::Exp* e = todo.top().exp;
611 todo.push(e->data.kids[1]);
612 todo.push(e->data.kids[0]);
613 } else {
614 todo.pop();
615 NodeInfo ni1 = done.pop();
616 NodeInfo ni0 = done.pop();
617 for (PosSet* ps = ni0.lastpos; ps != nullptr; ps = ps->next)
618 pi[ps->pos].followpos =
619 PosSet::cup(psm,pi[ps->pos].followpos,ni1.firstpos);
620 done.push(NodeInfo(ni0.nullable & ni1.nullable,
621 ni0.nullable ?
622 PosSet::cup(psm,ni0.firstpos,ni1.firstpos) : ni0.firstpos,
623 ni1.nullable ?
624 PosSet::cup(psm,ni0.lastpos,ni1.lastpos) : ni1.lastpos));
625 }
626 break;
627 case ET_OR:
628 if (todo.top().open) {
629 // Evaluate subexpressions recursively
630 todo.top().open = false;
631 REG::Exp* e = todo.top().exp;
632 todo.push(e->data.kids[1]);
633 todo.push(e->data.kids[0]);
634 } else {
635 todo.pop();
636 NodeInfo ni1 = done.pop();
637 NodeInfo ni0 = done.pop();
638 done.push(NodeInfo(ni0.nullable | ni1.nullable,
639 PosSet::cup(psm,ni0.firstpos,ni1.firstpos),
640 PosSet::cup(psm,ni0.lastpos,ni1.lastpos)));
641 }
642 break;
643 default: GECODE_NEVER;
644 }
645 }
646 } while (!todo.empty());
647 return done.top().firstpos;
648 }
649
650
651 namespace MiniModel {
652
653 class StateNode;
654
659
663 class StateNode : public Support::BlockClient<StateNode,Heap> {
664 public:
666 int state;
670 };
671
675 class StatePool {
676 public:
681
683
684 StateNode* pop(void);
685 bool empty(void) const;
686
688 };
689
692 next = &root;
693 all = nullptr;
694 n_states = 1;
695 root.pos = ps;
696 root.state = 0;
697 root.next = nullptr;
698 root.left = nullptr;
699 root.right = nullptr;
700 }
701
704 StateNode* n = next;
705 next = n->next;
706 n->next = all;
707 all = n;
708 return n;
709 }
710
711 forceinline bool
712 StatePool::empty(void) const {
713 return next == nullptr;
714 }
715
716 forceinline int
718 StateNode** p = nullptr;
719 StateNode* n = &root;
720 do {
721 switch (PosSet::cmp(ps,n->pos)) {
722 case PSC_EQ: return n->state;
723 case PSC_LE: p = &n->left; n = *p; break;
724 case PSC_GR: p = &n->right; n = *p; break;
725 default: GECODE_NEVER;
726 }
727 } while (n != nullptr);
728 n = new (spm) StateNode; *p = n;
729 n->pos = ps;
730 n->state = n_states++;
731 n->next = next;
732 n->left = nullptr;
733 n->right = nullptr;
734 next = n;
735 return n->state;
736 }
737
742 public:
743 forceinline bool
744 operator ()(int x, int y) {
745 return x < y;
746 }
747 forceinline static void
748 sort(int s[], int n) {
749 SymbolsInc o;
751 }
752 };
753
754
760 private:
762 int n;
763 public:
764 TransitionBag(void);
765 void add(int,int,int);
766 void finish(void);
768 };
769
772
773 forceinline void
774 TransitionBag::add(int i_state, int symbol, int o_state) {
775 t[n].i_state = i_state;
776 t[n].symbol = symbol;
777 t[n].o_state = o_state;
778 n++;
779 }
780
781 forceinline void
783 t[n].i_state = -1;
784 }
785
788 return &t[0];
789 }
790
791
796 class FinalBag {
797 private:
799 int n;
800 public:
801 FinalBag(void);
802 void add(int);
803 void finish(void);
804 int* finals(void);
805 };
806
808 FinalBag::FinalBag(void) : f(heap), n(0) {}
809
810 forceinline void
811 FinalBag::add(int state) {
812 f[n++] = state;
813 }
814
815 forceinline void
817 f[n] = -1;
818 }
819
820 forceinline int*
822 return &f[0];
823 }
824
825 }
826
827 REG::operator DFA(void) {
830 using MiniModel::PosInfo;
831 using MiniModel::PosSet;
833
836
839
841
842 Region region;
843 PosSetAllocator psm(region);
844 StatePoolAllocator spm(heap);
845 REG r = *this + REG(Int::Limits::max+1);
846 int n_pos = REG::Exp::n_pos(r.e);
847
848 PosInfo* pi = region.alloc<PosInfo>(n_pos);
849 for (int i=n_pos; i--; )
850 pi[i].followpos = nullptr;
851
852 PosSet* firstpos = r.e->followpos(psm,&pi[0]);
853
854 // Compute symbols
855 int* symbols = region.alloc<int>(n_pos);
856 for (int i=n_pos; i--; )
857 symbols[i] = pi[i].symbol;
858
859 SymbolsInc::sort(&symbols[0],n_pos-1);
860 int n_symbols = 1;
861 for (int i = 1; i<n_pos-1; i++)
862 if (symbols[i-1] != symbols[i])
863 symbols[n_symbols++] = symbols[i];
864
865 // Compute states and transitions
866 TransitionBag tb;
867 StatePool sp(firstpos);
868 while (!sp.empty()) {
869 StateNode* sn = sp.pop();
870 for (int i = n_symbols; i--; ) {
871 PosSet* u = nullptr;
872 for (PosSet* ps = sn->pos; ps != nullptr; ps = ps->next)
873 if (pi[ps->pos].symbol == symbols[i])
874 u = PosSet::cup(psm,u,pi[ps->pos].followpos);
875 if (u != nullptr)
876 tb.add(sn->state,symbols[i],sp.state(spm,u));
877 }
878 }
879 tb.finish();
880
881 // Compute final states
882 FinalBag fb;
883 for (StateNode* n = sp.all; n != nullptr; n = n->next)
884 if (n->pos->in(n_pos-1))
885 fb.add(n->state);
886 fb.finish();
887
888 return DFA(0,tb.transitions(),fb.finals(),true);
889 }
890
891}
892
893// STATISTICS: minimodel-any
894
int size(void) const
Return size of array (number of elements).
Definition array.hpp:1597
Specification of a DFA transition.
Definition int.hh:2212
Deterministic finite automaton (DFA).
Definition int.hh:2203
Passing integer arguments.
Definition int.hh:652
Expression information.
Definition reg.cpp:535
ExpInfo(REG::Exp *e=nullptr)
Definition reg.cpp:557
For collecting final states while constructing a DFA.
Definition reg.cpp:796
Node information computed during traversal of the expressions.
Definition reg.cpp:526
NodeInfo(bool n=false, PosSet *fp=nullptr, PosSet *lp=nullptr)
Definition reg.cpp:553
Information on positions collected during traversal.
Definition reg.cpp:546
Sets of positions.
Definition reg.cpp:452
static PosSet * cup(PosSetAllocator &, PosSet *, PosSet *)
Definition reg.cpp:502
bool in(int) const
Definition reg.cpp:475
static PosSetCmp cmp(PosSet *, PosSet *)
Definition reg.cpp:486
Node together with state information
Definition reg.cpp:663
State pool combines a tree of states together with yet unprocessed states
Definition reg.cpp:675
int state(StatePoolAllocator &, PosSet *)
Definition reg.cpp:717
StateNode * pop(void)
Definition reg.cpp:703
bool empty(void) const
Definition reg.cpp:712
static void sort(int s[], int n)
Definition reg.cpp:748
Exception: Too few arguments available in argument array
Definition exception.hpp:45
For collecting transitions while constructing a DFA.
Definition reg.cpp:759
DFA::Transition * transitions(void)
Definition reg.cpp:787
void add(int, int, int)
Definition reg.cpp:774
Implementation of the actual expression tree.
Definition reg.cpp:52
std::string toString(void) const
Print expression.
Definition reg.cpp:215
MiniModel::PosSet * followpos(MiniModel::PosSetAllocator &, MiniModel::PosInfo *)
Compute the follow positions.
Definition reg.cpp:563
Exp * kids[2]
Subexpressions.
Definition reg.cpp:74
ExpType type
Type of regular expression.
Definition reg.cpp:68
static int n_pos(Exp *e)
Return number of positions of e.
Definition reg.cpp:149
unsigned int use_cnt
Reference counter.
Definition reg.cpp:55
union Gecode::REG::Exp::@006363043156204252347047222243062210172322043104 data
Symbol or subexpressions.
static void dec(Exp *e)
Decrement use counter of e.
Definition reg.cpp:142
int symbol
Symbol.
Definition reg.cpp:72
void toString(std::ostringstream &os) const
Print expression to os.
Definition reg.cpp:154
static void inc(Exp *e)
Increment use counter of e.
Definition reg.cpp:137
int _n_pos
Number of positions.
Definition reg.cpp:57
ExpType
Type of regular expression.
Definition reg.cpp:61
Regular expressions over integer values.
~REG(void)
Destructor.
Definition reg.cpp:246
REG operator*(void)
Return expression for: this expression arbitrarily often (Kleene star).
Definition reg.cpp:361
const REG & operator=(const REG &r)
Assign to regular expression r.
Definition reg.cpp:237
REG & operator+=(const REG &r)
This expression is followed by r.
Definition reg.cpp:343
REG & operator|=(const REG &r)
This expression or r.
Definition reg.cpp:315
friend class MiniModel::ExpInfo
REG(void)
Initialize as empty sequence (epsilon).
Definition reg.cpp:230
REG operator()(unsigned int n, unsigned int m)
Return expression for: this expression at least n and at most m times.
Definition reg.cpp:374
REG operator+(void)
Return expression for: this expression at least once.
Definition reg.cpp:421
REG operator|(const REG &r)
Return expression for: this expression or r.
Definition reg.cpp:301
Handle to region.
Definition region.hpp:55
T * alloc(long unsigned int n)
Allocate block of n objects of type T from region.
Definition region.hpp:386
Manage memory organized into block lists (allocator).
Client for block allocator of type T.
Array with arbitrary number of elements.
Stack with arbitrary number of elements.
void push(const T &x)
Push element x on top of stack.
bool empty(void) const
Test whether stack is empty.
T pop(void)
Pop topmost element from stack and return it.
T & top(void) const
Return element on top of stack.
const int * pi[]
Definition photo.cpp:14262
Heap heap
The single global heap.
Definition heap.cpp:44
const int max
Largest allowed integer value.
Definition int.hh:120
Minimalistic modeling support.
Definition minimodel.hh:100
Support::BlockAllocator< PosSet, Region > PosSetAllocator
Allocator for position sets.
Definition reg.cpp:44
Support::BlockAllocator< StateNode, Heap > StatePoolAllocator
Allocator for state nodes.
Definition reg.cpp:658
PosSetCmp
Order on position sets.
Definition reg.cpp:443
void quicksort(Type *l, Type *r, Less &less)
Standard quick sort.
Definition sort.hpp:130
Gecode toplevel namespace
#define forceinline
Definition config.hpp:141
#define GECODE_NEVER
Assert that this command is never executed.
Definition macros.hpp:56