| 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) { |