this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.org>
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.org
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 <climits>
35#include <algorithm>
36
37namespace Gecode { namespace Int { namespace Extensional {
38
39 /**
40 * \brief Traits class for variables
41 *
42 * Each variable must specialize this traits class and add a \code
43 * typedef \endcode for the view \a View corresponding to this variable.
44 */
45 template<class Var>
46 class VarTraits {};
47
48 /**
49 * \brief Traits class for variables
50 *
51 * This class specializes the VarTraits for integer variables.
52 */
53 template<>
54 class VarTraits<IntVar> {
55 public:
56 /// The variable type of an IntView
57 typedef Int::IntView View;
58 };
59
60 /**
61 * \brief Traits class for variables
62 *
63 * This class specializes the VarTraits for Boolean variables.
64 */
65 template<>
66 class VarTraits<BoolVar> {
67 public:
68 /// The variable type of an IntView
69 typedef Int::BoolView View;
70 };
71
72
73 /*
74 * States
75 */
76 template<class View, class Val, class Degree, class StateIdx>
77 forceinline void
78 LayeredGraph<View,Val,Degree,StateIdx>::State::init(void) {
79 i_deg=o_deg=0;
80 }
81
82
83 template<class View, class Val, class Degree, class StateIdx>
84 forceinline typename LayeredGraph<View,Val,Degree,StateIdx>::State&
85 LayeredGraph<View,Val,Degree,StateIdx>::i_state(int i, StateIdx is) {
86 return layers[i].states[is];
87 }
88 template<class View, class Val, class Degree, class StateIdx>
89 forceinline typename LayeredGraph<View,Val,Degree,StateIdx>::State&
90 LayeredGraph<View,Val,Degree,StateIdx>::i_state
91 (int i, const typename LayeredGraph<View,Val,Degree,StateIdx>::Edge& e) {
92 return i_state(i,e.i_state);
93 }
94 template<class View, class Val, class Degree, class StateIdx>
95 forceinline bool
96 LayeredGraph<View,Val,Degree,StateIdx>::i_dec
97 (int i, const typename LayeredGraph<View,Val,Degree,StateIdx>::Edge& e) {
98 return --i_state(i,e).o_deg == 0;
99 }
100 template<class View, class Val, class Degree, class StateIdx>
101 forceinline typename LayeredGraph<View,Val,Degree,StateIdx>::State&
102 LayeredGraph<View,Val,Degree,StateIdx>::o_state(int i, StateIdx os) {
103 return layers[i+1].states[os];
104 }
105 template<class View, class Val, class Degree, class StateIdx>
106 forceinline typename LayeredGraph<View,Val,Degree,StateIdx>::State&
107 LayeredGraph<View,Val,Degree,StateIdx>::o_state
108 (int i, const typename LayeredGraph<View,Val,Degree,StateIdx>::Edge& e) {
109 return o_state(i,e.o_state);
110 }
111 template<class View, class Val, class Degree, class StateIdx>
112 forceinline bool
113 LayeredGraph<View,Val,Degree,StateIdx>::o_dec
114 (int i, const typename LayeredGraph<View,Val,Degree,StateIdx>::Edge& e) {
115 return --o_state(i,e).i_deg == 0;
116 }
117
118
119 /*
120 * Value iterator
121 */
122 template<class View, class Val, class Degree, class StateIdx>
123 forceinline
124 LayeredGraph<View,Val,Degree,StateIdx>::LayerValues::LayerValues(void) {}
125 template<class View, class Val, class Degree, class StateIdx>
126 forceinline
127 LayeredGraph<View,Val,Degree,StateIdx>::LayerValues
128 ::LayerValues(const Layer& l)
129 : s1(l.support), s2(l.support+l.size) {}
130 template<class View, class Val, class Degree, class StateIdx>
131 forceinline void
132 LayeredGraph<View,Val,Degree,StateIdx>::LayerValues::init(const Layer& l) {
133 s1=l.support; s2=l.support+l.size;
134 }
135 template<class View, class Val, class Degree, class StateIdx>
136 forceinline bool
137 LayeredGraph<View,Val,Degree,StateIdx>::LayerValues
138 ::operator ()(void) const {
139 return s1<s2;
140 }
141 template<class View, class Val, class Degree, class StateIdx>
142 forceinline void
143 LayeredGraph<View,Val,Degree,StateIdx>::LayerValues::operator ++(void) {
144 s1++;
145 }
146 template<class View, class Val, class Degree, class StateIdx>
147 forceinline int
148 LayeredGraph<View,Val,Degree,StateIdx>::LayerValues::val(void) const {
149 return s1->val;
150 }
151
152
153 /*
154 * Index advisors
155 *
156 */
157 template<class View, class Val, class Degree, class StateIdx>
158 forceinline
159 LayeredGraph<View,Val,Degree,StateIdx>::Index::Index(Space& home, Propagator& p,
160 Council<Index>& c,
161 int i0)
162 : Advisor(home,p,c), i(i0) {}
163
164 template<class View, class Val, class Degree, class StateIdx>
165 forceinline
166 LayeredGraph<View,Val,Degree,StateIdx>::Index::Index(Space& home, Index& a)
167 : Advisor(home,a), i(a.i) {}
168
169
170 /*
171 * Index ranges
172 *
173 */
174 template<class View, class Val, class Degree, class StateIdx>
175 forceinline
176 LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::IndexRange(void)
177 : _fst(INT_MAX), _lst(INT_MIN) {}
178 template<class View, class Val, class Degree, class StateIdx>
179 forceinline void
180 LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::reset(void) {
181 _fst=INT_MAX; _lst=INT_MIN;
182 }
183 template<class View, class Val, class Degree, class StateIdx>
184 forceinline void
185 LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::add(int i) {
186 _fst=std::min(_fst,i); _lst=std::max(_lst,i);
187 }
188 template<class View, class Val, class Degree, class StateIdx>
189 forceinline void
190 LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::add
191 (const typename LayeredGraph<View,Val,Degree,StateIdx>::IndexRange& ir) {
192 _fst=std::min(_fst,ir._fst); _lst=std::max(_lst,ir._lst);
193 }
194 template<class View, class Val, class Degree, class StateIdx>
195 forceinline bool
196 LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::empty(void) const {
197 return _fst>_lst;
198 }
199 template<class View, class Val, class Degree, class StateIdx>
200 forceinline void
201 LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::lshift(int n) {
202 if (empty())
203 return;
204 if (n > _lst) {
205 reset();
206 } else {
207 _fst = std::max(0,_fst-n);
208 _lst -= n;
209 }
210 }
211 template<class View, class Val, class Degree, class StateIdx>
212 forceinline int
213 LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::fst(void) const {
214 return _fst;
215 }
216 template<class View, class Val, class Degree, class StateIdx>
217 forceinline int
218 LayeredGraph<View,Val,Degree,StateIdx>::IndexRange::lst(void) const {
219 return _lst;
220 }
221
222
223
224 /*
225 * The layered graph
226 *
227 */
228
229 template<class View, class Val, class Degree, class StateIdx>
230 template<class Var>
231 forceinline
232 LayeredGraph<View,Val,Degree,StateIdx>::LayeredGraph(Home home,
233 const VarArgArray<Var>& x,
234 const DFA& dfa)
235 : Propagator(home), c(home), n(x.size()),
236 max_states(static_cast<StateIdx>(dfa.n_states())) {
237 assert(n > 0);
238 }
239
240 template<class View, class Val, class Degree, class StateIdx>
241 forceinline void
242 LayeredGraph<View,Val,Degree,StateIdx>::audit(void) {
243#ifdef GECODE_AUDIT
244 // Check states and edge information to be consistent
245 unsigned int n_e = 0; // Number of edges
246 unsigned int n_s = 0; // Number of states
247 StateIdx m_s = 0; // Maximal number of states per layer
248 for (int i=n; i--; ) {
249 n_s += layers[i].n_states;
250 m_s = std::max(m_s,layers[i].n_states);
251 for (ValSize j=layers[i].size; j--; )
252 n_e += layers[i].support[j].n_edges;
253 }
254 n_s += layers[n].n_states;
255 m_s = std::max(m_s,layers[n].n_states);
256 assert(n_e == n_edges);
257 assert(n_s <= n_states);
258 assert(m_s <= max_states);
259#endif
260 }
261
262 template<class View, class Val, class Degree, class StateIdx>
263 template<class Var>
264 forceinline ExecStatus
265 LayeredGraph<View,Val,Degree,StateIdx>::initialize(Space& home,
266 const VarArgArray<Var>& x,
267 const DFA& dfa) {
268
269 Region r;
270
271 // Allocate memory for layers
272 layers = home.alloc<Layer>(n+1);
273
274 // Allocate temporary memory for all possible states
275 State* states = r.alloc<State>(max_states*(n+1));
276 for (int i=0; i<static_cast<int>(max_states)*(n+1); i++)
277 states[i].init();
278 for (int i=0; i<n+1; i++)
279 layers[i].states = states + i*max_states;
280
281 // Allocate temporary memory for edges
282 Edge* edges = r.alloc<Edge>(dfa.max_degree());
283
284 // Mark initial state as being reachable
285 i_state(0,0).i_deg = 1;
286
287 // Forward pass: add transitions
288 for (int i=0; i<n; i++) {
289 layers[i].x = x[i];
290 layers[i].support = home.alloc<Support>(layers[i].x.size());
291 ValSize j=0;
292 // Enter links leaving reachable states (indegree != 0)
293 for (ViewValues<View> nx(layers[i].x); nx(); ++nx) {
294 Degree n_edges=0;
295 for (DFA::Transitions t(dfa,nx.val()); t(); ++t)
296 if (i_state(i,static_cast<StateIdx>(t.i_state())).i_deg != 0) {
297 i_state(i,static_cast<StateIdx>(t.i_state())).o_deg++;
298 o_state(i,static_cast<StateIdx>(t.o_state())).i_deg++;
299 edges[n_edges].i_state = static_cast<StateIdx>(t.i_state());
300 edges[n_edges].o_state = static_cast<StateIdx>(t.o_state());
301 n_edges++;
302 }
303 assert(n_edges <= dfa.max_degree());
304 // Found support for value
305 if (n_edges > 0) {
306 Support& s = layers[i].support[j];
307 s.val = static_cast<Val>(nx.val());
308 s.n_edges = n_edges;
309 s.edges = Heap::copy(home.alloc<Edge>(n_edges),edges,n_edges);
310 j++;
311 }
312 }
313 if ((layers[i].size = j) == 0)
314 return ES_FAILED;
315 }
316
317 // Mark final states as reachable
318 for (int s=dfa.final_fst(); s<dfa.final_lst(); s++)
319 if (o_state(n-1,static_cast<StateIdx>(s)).i_deg != 0)
320 o_state(n-1,static_cast<StateIdx>(s)).o_deg = 1;
321
322 // Backward pass: prune all transitions that do not lead to final state
323 for (int i=n; i--; ) {
324 ValSize k=0;
325 for (ValSize j=0; j<layers[i].size; j++) {
326 Support& s = layers[i].support[j];
327 for (Degree d=s.n_edges; d--; )
328 if (o_state(i,s.edges[d]).o_deg == 0) {
329 // Adapt states
330 i_dec(i,s.edges[d]); o_dec(i,s.edges[d]);
331 // Prune edge
332 s.edges[d] = s.edges[--s.n_edges];
333 }
334 // Value has support, copy the support information
335 if (s.n_edges > 0)
336 layers[i].support[k++]=s;
337 }
338 if ((layers[i].size = k) == 0)
339 return ES_FAILED;
340 LayerValues lv(layers[i]);
341 GECODE_ME_CHECK(layers[i].x.narrow_v(home,lv,false));
342 if (!layers[i].x.assigned())
343 layers[i].x.subscribe(home, *new (home) Index(home,*this,c,i));
344 }
345
346 // Copy and compress states, setup other information
347 {
348 // State map for in-states
349 StateIdx* i_map = r.alloc<StateIdx>(max_states);
350 // State map for out-states
351 StateIdx* o_map = r.alloc<StateIdx>(max_states);
352 // Number of in-states
353 StateIdx i_n = 0;
354
355 // Initialize map for in-states (special for last layer)
356 // Degree for single final state
357 unsigned int d = 0;
358 for (StateIdx j=0; j<max_states; j++)
359 d += static_cast<unsigned int>(layers[n].states[j].i_deg);
360 // Check whether all final states can be joined to a single state
361 if (d >
362 static_cast<unsigned int>
363 (Gecode::Support::IntTypeTraits<Degree>::max)) {
364 // Initialize map for in-states
365 for (StateIdx j=max_states; j--; )
366 if ((layers[n].states[j].o_deg != 0) ||
367 (layers[n].states[j].i_deg != 0))
368 i_map[j]=i_n++;
369 } else {
370 i_n = 1;
371 for (StateIdx j=max_states; j--; ) {
372 layers[n].states[j].init();
373 i_map[j] = 0;
374 }
375 layers[n].states[0].i_deg = static_cast<Degree>(d);
376 layers[n].states[0].o_deg = 1;
377 }
378 layers[n].n_states = i_n;
379
380 // Total number of states
381 n_states = i_n;
382 // Total number of edges
383 n_edges = 0;
384 // New maximal number of states
385 StateIdx max_s = i_n;
386
387 for (int i=n; i--; ) {
388 // In-states become out-states
389 std::swap(o_map,i_map); i_n=0;
390 // Initialize map for in-states
391 for (StateIdx j=max_states; j--; )
392 if ((layers[i].states[j].o_deg != 0) ||
393 (layers[i].states[j].i_deg != 0))
394 i_map[j]=i_n++;
395 layers[i].n_states = i_n;
396 n_states += i_n;
397 max_s = std::max(max_s,i_n);
398
399 // Update states in edges
400 for (ValSize j=layers[i].size; j--; ) {
401 Support& ls = layers[i].support[j];
402 n_edges += ls.n_edges;
403 for (Degree deg=ls.n_edges; deg--; ) {
404 ls.edges[deg].i_state = i_map[ls.edges[deg].i_state];
405 ls.edges[deg].o_state = o_map[ls.edges[deg].o_state];
406 }
407 }
408 }
409
410 // Allocate and copy states
411 State* a_states = home.alloc<State>(n_states);
412 for (int i=n+1; i--; ) {
413 StateIdx k=0;
414 for (StateIdx j=max_states; j--; )
415 if ((layers[i].states[j].o_deg != 0) ||
416 (layers[i].states[j].i_deg != 0))
417 a_states[k++] = layers[i].states[j];
418 assert(k == layers[i].n_states);
419 layers[i].states = a_states;
420 a_states += layers[i].n_states;
421 }
422
423 // Update maximal number of states
424 max_states = max_s;
425 }
426
427 // Schedule if subsumption is needed
428 if (c.empty())
429 View::schedule(home,*this,ME_INT_VAL);
430
431 audit();
432 return ES_OK;
433 }
434
435 template<class View, class Val, class Degree, class StateIdx>
436 ExecStatus
437 LayeredGraph<View,Val,Degree,StateIdx>::advise(Space& home,
438 Advisor& _a, const Delta& d) {
439 // Check whether state information has already been created
440 if (layers[0].states == nullptr) {
441 State* states = home.alloc<State>(n_states);
442 for (unsigned int i=0; i<n_states; i++)
443 states[i].init();
444 layers[n].states = states;
445 states += layers[n].n_states;
446 for (int i=n; i--; ) {
447 layers[i].states = states;
448 states += layers[i].n_states;
449 for (ValSize j=layers[i].size; j--; ) {
450 Support& s = layers[i].support[j];
451 for (Degree deg=s.n_edges; deg--; ) {
452 i_state(i,s.edges[deg]).o_deg++;
453 o_state(i,s.edges[deg]).i_deg++;
454 }
455 }
456 }
457 }
458
459 Index& a = static_cast<Index&>(_a);
460 const int i = a.i;
461
462 if (layers[i].size <= layers[i].x.size()) {
463 // Propagator has already done everything
464 if (View::modevent(d) == ME_INT_VAL) {
465 a.dispose(home,c);
466 return c.empty() ? ES_NOFIX : ES_FIX;
467 } else {
468 return ES_FIX;
469 }
470 }
471
472 bool i_mod = false;
473 bool o_mod = false;
474
475 if (View::modevent(d) == ME_INT_VAL) {
476 Val n = static_cast<Val>(layers[i].x.val());
477 ValSize j=0;
478 for (; layers[i].support[j].val < n; j++) {
479 Support& s = layers[i].support[j];
480 n_edges -= s.n_edges;
481 // Supported value not any longer in view
482 for (Degree deg=s.n_edges; deg--; ) {
483 // Adapt states
484 o_mod |= i_dec(i,s.edges[deg]);
485 i_mod |= o_dec(i,s.edges[deg]);
486 }
487 }
488 assert(layers[i].support[j].val == n);
489 layers[i].support[0] = layers[i].support[j++];
490 ValSize s=layers[i].size;
491 layers[i].size = 1;
492 for (; j<s; j++) {
493 Support& ls = layers[i].support[j];
494 n_edges -= ls.n_edges;
495 for (Degree deg=ls.n_edges; deg--; ) {
496 // Adapt states
497 o_mod |= i_dec(i,ls.edges[deg]);
498 i_mod |= o_dec(i,ls.edges[deg]);
499 }
500 }
501 } else if (layers[i].x.any(d)) {
502 ValSize j=0;
503 ValSize k=0;
504 ValSize s=layers[i].size;
505 for (ViewRanges<View> rx(layers[i].x); rx() && (j<s);) {
506 Support& ls = layers[i].support[j];
507 if (ls.val < static_cast<Val>(rx.min())) {
508 // Supported value not any longer in view
509 n_edges -= ls.n_edges;
510 for (Degree deg=ls.n_edges; deg--; ) {
511 // Adapt states
512 o_mod |= i_dec(i,ls.edges[deg]);
513 i_mod |= o_dec(i,ls.edges[deg]);
514 }
515 ++j;
516 } else if (ls.val > static_cast<Val>(rx.max())) {
517 ++rx;
518 } else {
519 layers[i].support[k++]=ls;
520 ++j;
521 }
522 }
523 assert(k > 0);
524 layers[i].size = k;
525 // Remove remaining values
526 for (; j<s; j++) {
527 Support& ls=layers[i].support[j];
528 n_edges -= ls.n_edges;
529 for (Degree deg=ls.n_edges; deg--; ) {
530 // Adapt states
531 o_mod |= i_dec(i,ls.edges[deg]);
532 i_mod |= o_dec(i,ls.edges[deg]);
533 }
534 }
535 } else {
536 Val min = static_cast<Val>(layers[i].x.min(d));
537 ValSize j=0;
538 // Skip values smaller than min (to keep)
539 for (; layers[i].support[j].val < min; j++) {}
540 Val max = static_cast<Val>(layers[i].x.max(d));
541 ValSize k=j;
542 ValSize s=layers[i].size;
543 // Remove pruned values
544 for (; (j<s) && (layers[i].support[j].val <= max); j++) {
545 Support& ls=layers[i].support[j];
546 n_edges -= ls.n_edges;
547 for (Degree deg=ls.n_edges; deg--; ) {
548 // Adapt states
549 o_mod |= i_dec(i,ls.edges[deg]);
550 i_mod |= o_dec(i,ls.edges[deg]);
551 }
552 }
553 // Keep remaining values
554 while (j<s)
555 layers[i].support[k++]=layers[i].support[j++];
556 layers[i].size=k;
557 assert(k > 0);
558 }
559
560 audit();
561
562 bool fix = true;
563 if (o_mod && (i > 0)) {
564 o_ch.add(i-1); fix = false;
565 }
566 if (i_mod && (i+1 < n)) {
567 i_ch.add(i+1); fix = false;
568 }
569 if (fix) {
570 if (View::modevent(d) == ME_INT_VAL) {
571 a.dispose(home,c);
572 return c.empty() ? ES_NOFIX : ES_FIX;
573 }
574 return ES_FIX;
575 } else {
576 return (View::modevent(d) == ME_INT_VAL)
577 ? home.ES_NOFIX_DISPOSE(c,a) : ES_NOFIX;
578 }
579 }
580
581 template<class View, class Val, class Degree, class StateIdx>
582 forceinline size_t
583 LayeredGraph<View,Val,Degree,StateIdx>::dispose(Space& home) {
584 c.dispose(home);
585 (void) Propagator::dispose(home);
586 return sizeof(*this);
587 }
588
589 template<class View, class Val, class Degree, class StateIdx>
590 void
591 LayeredGraph<View,Val,Degree,StateIdx>::reschedule(Space& home) {
592 View::schedule(home,*this,c.empty() ? ME_INT_VAL : ME_INT_DOM);
593 }
594
595 template<class View, class Val, class Degree, class StateIdx>
596 ExecStatus
597 LayeredGraph<View,Val,Degree,StateIdx>::propagate(Space& home,
598 const ModEventDelta&) {
599 // Forward pass
600 for (int i=i_ch.fst(); i<=i_ch.lst(); i++) {
601 bool i_mod = false;
602 bool o_mod = false;
603 ValSize j=0;
604 ValSize k=0;
605 ValSize ls=layers[i].size;
606 do {
607 Support& s=layers[i].support[j];
608 n_edges -= s.n_edges;
609 for (Degree d=s.n_edges; d--; )
610 if (i_state(i,s.edges[d]).i_deg == 0) {
611 // Adapt states
612 o_mod |= i_dec(i,s.edges[d]);
613 i_mod |= o_dec(i,s.edges[d]);
614 // Remove edge
615 s.edges[d] = s.edges[--s.n_edges];
616 }
617 n_edges += s.n_edges;
618 // Check whether value is still supported
619 if (s.n_edges == 0) {
620 layers[i].size--;
621 GECODE_ME_CHECK(layers[i].x.nq(home,s.val));
622 } else {
623 layers[i].support[k++]=s;
624 }
625 } while (++j<ls);
626 assert(k > 0);
627 // Update modification information
628 if (o_mod && (i > 0))
629 o_ch.add(i-1);
630 if (i_mod && (i+1 < n))
631 i_ch.add(i+1);
632 }
633
634 // Backward pass
635 for (int i=o_ch.lst(); i>=o_ch.fst(); i--) {
636 bool o_mod = false;
637 ValSize j=0;
638 ValSize k=0;
639 ValSize ls=layers[i].size;
640 do {
641 Support& s=layers[i].support[j];
642 n_edges -= s.n_edges;
643 for (Degree d=s.n_edges; d--; )
644 if (o_state(i,s.edges[d]).o_deg == 0) {
645 // Adapt states
646 o_mod |= i_dec(i,s.edges[d]);
647 (void) o_dec(i,s.edges[d]);
648 // Remove edge
649 s.edges[d] = s.edges[--s.n_edges];
650 }
651 n_edges += s.n_edges;
652 // Check whether value is still supported
653 if (s.n_edges == 0) {
654 layers[i].size--;
655 GECODE_ME_CHECK(layers[i].x.nq(home,s.val));
656 } else {
657 layers[i].support[k++]=s;
658 }
659 } while (++j<ls);
660 assert(k > 0);
661 // Update modification information
662 if (o_mod && (i > 0))
663 o_ch.add(i-1);
664 }
665
666 a_ch.add(i_ch); i_ch.reset();
667 a_ch.add(o_ch); o_ch.reset();
668
669 audit();
670
671 // Check subsumption
672 if (c.empty())
673 return home.ES_SUBSUMED(*this);
674 else
675 return ES_FIX;
676 }
677
678
679 template<class View, class Val, class Degree, class StateIdx>
680 template<class Var>
681 ExecStatus
682 LayeredGraph<View,Val,Degree,StateIdx>::post(Home home,
683 const VarArgArray<Var>& x,
684 const DFA& dfa) {
685 if (x.size() == 0) {
686 // Check whether the start state 0 is also a final state
687 if ((dfa.final_fst() <= 0) && (dfa.final_lst() >= 0))
688 return ES_OK;
689 return ES_FAILED;
690 }
691 assert(x.size() > 0);
692 for (int i=0; i<x.size(); i++) {
693 DFA::Symbols s(dfa);
694 typename VarTraits<Var>::View xi(x[i]);
695 GECODE_ME_CHECK(xi.inter_v(home,s,false));
696 }
697 LayeredGraph<View,Val,Degree,StateIdx>* p =
698 new (home) LayeredGraph<View,Val,Degree,StateIdx>(home,x,dfa);
699 return p->initialize(home,x,dfa);
700 }
701
702 template<class View, class Val, class Degree, class StateIdx>
703 forceinline
704 LayeredGraph<View,Val,Degree,StateIdx>
705 ::LayeredGraph(Space& home, LayeredGraph<View,Val,Degree,StateIdx>& p)
706 : Propagator(home,p),
707 n(p.n), layers(home.alloc<Layer>(n+1)),
708 max_states(p.max_states), n_states(p.n_states), n_edges(p.n_edges) {
709 c.update(home,p.c);
710 // Do not allocate states, postpone to advise!
711 layers[n].n_states = p.layers[n].n_states;
712 layers[n].states = nullptr;
713 // Allocate memory for edges
714 Edge* edges = home.alloc<Edge>(n_edges);
715 // Copy layers
716 for (int i=0; i<n; i++) {
717 layers[i].x.update(home,p.layers[i].x);
718 assert(layers[i].x.size() == p.layers[i].size);
719 layers[i].size = p.layers[i].size;
720 layers[i].support = home.alloc<Support>(layers[i].size);
721 for (ValSize j=0; j<layers[i].size; j++) {
722 layers[i].support[j].val = p.layers[i].support[j].val;
723 layers[i].support[j].n_edges = p.layers[i].support[j].n_edges;
724 assert(layers[i].support[j].n_edges > 0);
725 layers[i].support[j].edges =
726 Heap::copy(edges,p.layers[i].support[j].edges,
727 layers[i].support[j].n_edges);
728 edges += layers[i].support[j].n_edges;
729 }
730 layers[i].n_states = p.layers[i].n_states;
731 layers[i].states = nullptr;
732 }
733 audit();
734 }
735
736 template<class View, class Val, class Degree, class StateIdx>
737 PropCost
738 LayeredGraph<View,Val,Degree,StateIdx>::cost(const Space&,
739 const ModEventDelta&) const {
740 return PropCost::linear(PropCost::HI,n);
741 }
742
743 template<class View, class Val, class Degree, class StateIdx>
744 Actor*
745 LayeredGraph<View,Val,Degree,StateIdx>::copy(Space& home) {
746 // Eliminate an assigned prefix
747 {
748 int k=0;
749 while (layers[k].size == 1) {
750 assert(layers[k].support[0].n_edges == 1);
751 n_states -= layers[k].n_states;
752 k++;
753 }
754 if (k > 0) {
755 /*
756 * The state information is always available: either the propagator
757 * has been created (hence, also the state information has been
758 * created), or the first variable become assigned and hence
759 * an advisor must have been run (which then has created the state
760 * information).
761 */
762 // Eliminate assigned layers
763 n -= k; layers += k;
764 // Eliminate edges
765 n_edges -= static_cast<unsigned int>(k);
766 // Update advisor indices
767 for (Advisors<Index> as(c); as(); ++as)
768 as.advisor().i -= k;
769 // Update all change information
770 a_ch.lshift(k);
771 }
772 }
773 audit();
774
775 // Compress states
776 if (!a_ch.empty()) {
777 int f = a_ch.fst();
778 int l = a_ch.lst();
779 assert((f >= 0) && (l <= n));
780 Region r;
781 // State map for in-states
782 StateIdx* i_map = r.alloc<StateIdx>(max_states);
783 // State map for out-states
784 StateIdx* o_map = r.alloc<StateIdx>(max_states);
785 // Number of in-states
786 StateIdx i_n = 0;
787
788 n_states -= layers[l].n_states;
789 // Initialize map for in-states and compress
790 for (StateIdx j=0; j<layers[l].n_states; j++)
791 if ((layers[l].states[j].i_deg != 0) ||
792 (layers[l].states[j].o_deg != 0)) {
793 layers[l].states[i_n]=layers[l].states[j];
794 i_map[j]=i_n++;
795 }
796 layers[l].n_states = i_n;
797 n_states += layers[l].n_states;
798 assert(i_n > 0);
799
800 // Update in-states in edges for last layer, if any
801 if (l < n)
802 for (ValSize j=layers[l].size; j--; ) {
803 Support& s = layers[l].support[j];
804 for (Degree d=s.n_edges; d--; )
805 s.edges[d].i_state = i_map[s.edges[d].i_state];
806 }
807
808 // Update all changed layers
809 for (int i=l-1; i>=f; i--) {
810 // In-states become out-states
811 std::swap(o_map,i_map); i_n=0;
812 // Initialize map for in-states and compress
813 n_states -= layers[i].n_states;
814 for (StateIdx j=0; j<layers[i].n_states; j++)
815 if ((layers[i].states[j].o_deg != 0) ||
816 (layers[i].states[j].i_deg != 0)) {
817 layers[i].states[i_n]=layers[i].states[j];
818 i_map[j]=i_n++;
819 }
820 layers[i].n_states = i_n;
821 n_states += layers[i].n_states;
822 assert(i_n > 0);
823
824 // Update states in edges
825 for (ValSize j=layers[i].size; j--; ) {
826 Support& s = layers[i].support[j];
827 for (Degree d=s.n_edges; d--; ) {
828 s.edges[d].i_state = i_map[s.edges[d].i_state];
829 s.edges[d].o_state = o_map[s.edges[d].o_state];
830 }
831 }
832 }
833
834 // Update out-states in edges for previous layer, if any
835 if (f > 0)
836 for (ValSize j=layers[f-1].size; j--; ) {
837 Support& s = layers[f-1].support[j];
838 for (Degree d=s.n_edges; d--; )
839 s.edges[d].o_state = i_map[s.edges[d].o_state];
840 }
841
842 a_ch.reset();
843 }
844 audit();
845
846 return new (home) LayeredGraph<View,Val,Degree,StateIdx>(home,*this);
847 }
848
849 /// Select small types for the layered graph propagator
850 template<class Var>
851 forceinline ExecStatus
852 post_lgp(Home home, const VarArgArray<Var>& x, const DFA& dfa) {
853 Gecode::Support::IntType t_state_idx =
854 Gecode::Support::u_type(static_cast<unsigned int>(dfa.n_states()));
855 Gecode::Support::IntType t_degree =
856 Gecode::Support::u_type(dfa.max_degree());
857 Gecode::Support::IntType t_val =
858 std::max(Support::s_type(dfa.symbol_min()),
859 Support::s_type(dfa.symbol_max()));
860 switch (t_val) {
861 case Gecode::Support::IT_CHAR:
862 // fall through
863 case Gecode::Support::IT_SHRT:
864 switch (t_state_idx) {
865 case Gecode::Support::IT_CHAR:
866 switch (t_degree) {
867 case Gecode::Support::IT_CHAR:
868 return Extensional::LayeredGraph
869 <typename VarTraits<Var>::View,short int,unsigned char,unsigned char>
870 ::post(home,x,dfa);
871 case Gecode::Support::IT_SHRT:
872 return Extensional::LayeredGraph
873 <typename VarTraits<Var>::View,short int,unsigned short int,unsigned char>
874 ::post(home,x,dfa);
875 case Gecode::Support::IT_INT:
876 return Extensional::LayeredGraph
877 <typename VarTraits<Var>::View,short int,unsigned int,unsigned char>
878 ::post(home,x,dfa);
879 default: GECODE_NEVER;
880 }
881 break;
882 case Gecode::Support::IT_SHRT:
883 switch (t_degree) {
884 case Gecode::Support::IT_CHAR:
885 return Extensional::LayeredGraph
886 <typename VarTraits<Var>::View,short int,unsigned char,unsigned short int>
887 ::post(home,x,dfa);
888 case Gecode::Support::IT_SHRT:
889 return Extensional::LayeredGraph
890 <typename VarTraits<Var>::View,short int,unsigned short int,unsigned short int>
891 ::post(home,x,dfa);
892 case Gecode::Support::IT_INT:
893 return Extensional::LayeredGraph
894 <typename VarTraits<Var>::View,short int,unsigned int,unsigned short int>
895 ::post(home,x,dfa);
896 default: GECODE_NEVER;
897 }
898 break;
899 case Gecode::Support::IT_INT:
900 switch (t_degree) {
901 case Gecode::Support::IT_CHAR:
902 return Extensional::LayeredGraph
903 <typename VarTraits<Var>::View,short int,unsigned char,unsigned int>
904 ::post(home,x,dfa);
905 case Gecode::Support::IT_SHRT:
906 return Extensional::LayeredGraph
907 <typename VarTraits<Var>::View,short int,unsigned short int,unsigned int>
908 ::post(home,x,dfa);
909 case Gecode::Support::IT_INT:
910 return Extensional::LayeredGraph
911 <typename VarTraits<Var>::View,short int,unsigned int,unsigned int>
912 ::post(home,x,dfa);
913 default: GECODE_NEVER;
914 }
915 break;
916 default: GECODE_NEVER;
917 }
918 break;
919 case Gecode::Support::IT_INT:
920 switch (t_state_idx) {
921 case Gecode::Support::IT_CHAR:
922 switch (t_degree) {
923 case Gecode::Support::IT_CHAR:
924 return Extensional::LayeredGraph
925 <typename VarTraits<Var>::View,int,unsigned char,unsigned char>
926 ::post(home,x,dfa);
927 case Gecode::Support::IT_SHRT:
928 return Extensional::LayeredGraph
929 <typename VarTraits<Var>::View,int,unsigned short int,unsigned char>
930 ::post(home,x,dfa);
931 case Gecode::Support::IT_INT:
932 return Extensional::LayeredGraph
933 <typename VarTraits<Var>::View,int,unsigned int,unsigned char>
934 ::post(home,x,dfa);
935 default: GECODE_NEVER;
936 }
937 break;
938 case Gecode::Support::IT_SHRT:
939 switch (t_degree) {
940 case Gecode::Support::IT_CHAR:
941 return Extensional::LayeredGraph
942 <typename VarTraits<Var>::View,int,unsigned char,unsigned short int>
943 ::post(home,x,dfa);
944 case Gecode::Support::IT_SHRT:
945 return Extensional::LayeredGraph
946 <typename VarTraits<Var>::View,int,unsigned short int,unsigned short int>
947 ::post(home,x,dfa);
948 case Gecode::Support::IT_INT:
949 return Extensional::LayeredGraph
950 <typename VarTraits<Var>::View,int,unsigned int,unsigned short int>
951 ::post(home,x,dfa);
952 default: GECODE_NEVER;
953 }
954 break;
955 case Gecode::Support::IT_INT:
956 switch (t_degree) {
957 case Gecode::Support::IT_CHAR:
958 return Extensional::LayeredGraph
959 <typename VarTraits<Var>::View,int,unsigned char,unsigned int>
960 ::post(home,x,dfa);
961 case Gecode::Support::IT_SHRT:
962 return Extensional::LayeredGraph
963 <typename VarTraits<Var>::View,int,unsigned short int,unsigned int>
964 ::post(home,x,dfa);
965 case Gecode::Support::IT_INT:
966 return Extensional::LayeredGraph
967 <typename VarTraits<Var>::View,int,unsigned int,unsigned int>
968 ::post(home,x,dfa);
969 default: GECODE_NEVER;
970 }
971 break;
972 default: GECODE_NEVER;
973 }
974
975 default: GECODE_NEVER;
976 }
977 return ES_OK;
978 }
979
980}}}
981
982// STATISTICS: int-prop
983