Beispiel #1
0
 inline ExecStatus
 NaryNq<View>::post(Home home, ViewArray<View>& x) {
   x.unique(home);
   // Try to find an assigned view
   int n = x.size();
   if (n <= 1)
     return ES_FAILED;
   for (int i=n; i--; )
     if (x[i].assigned()) {
       std::swap(x[0],x[i]);
       break;
     }
   if (x[0].assigned()) {
     int v = x[0].val();
     // Eliminate all equal views and possibly find disequal view
     for (int i=n-1; i>0; i--)
       if (!x[i].in(v)) {
         return ES_OK;
       } else if (x[i].assigned()) {
         assert(x[i].val() == v);
         x[i]=x[--n];
       }
     x.size(n);
   }
   if (n == 1)
     return ES_FAILED;
   if (n == 2)
     return Nq<View>::post(home,x[0],x[1]);
   (void) new (home) NaryNq(home,x);
   return ES_OK;
 }
Beispiel #2
0
 ExecStatus
 EqBoolView<XV,YV>::post(Home home, ViewArray<XV>& x, YV y, int c) {
   if (y.assigned())
     return EqBoolInt<XV>::post(home,x,y.val()+c);
   int n = x.size();
   for (int i = n; i--; )
     if (x[i].one()) {
       x[i]=x[--n]; c--;
     } else if (x[i].zero()) {
       x[i]=x[--n];
     }
   x.size(n);
   GECODE_ME_CHECK(y.lq(home,n-c));
   GECODE_ME_CHECK(y.gq(home,-c));
   if (n == 0)
     return ES_OK;
   if (y.min()+c == n) {
     assert(y.assigned());
     for (int i = n; i--; )
       GECODE_ME_CHECK(x[i].one_none(home));
     return ES_OK;
   }
   if (y.max()+c == 0) {
     assert(y.assigned());
     for (int i = n; i--; )
       GECODE_ME_CHECK(x[i].zero_none(home));
     return ES_OK;
   }
   (void) new (home) EqBoolView<XV,YV>(home,x,y,c);
   return ES_OK;
 }
Beispiel #3
0
  inline ExecStatus
  Prop<View>::post(Home home, ViewArray<View>& x, View y) {
    if (x.size() == 0)
      return ES_FAILED;

    x.unique(home);

    if (x.size() == 1)
      return Rel::EqDom<View,View>::post(home,x[0],y);
    
    if (x.same(home,y))
      return ES_OK;

    // Eliminate assigned views and store them into the value set
    ValSet vs;
    add(home, vs, x);

    if (x.size() == 0) {
      ValSet::Ranges vsr(vs);
      GECODE_ME_CHECK(y.inter_r(home,vsr,false));
      return ES_OK;
    }

    (void) new (home) Prop<View>(home, vs, x, y);
    return ES_OK;
  }
 ExecStatus
 LqInt<VX,VY>::post(Home home, ViewArray<VX>& x, VY y, int c) {
   // Eliminate decided views
   int n_x = x.size();
   for (int i=n_x; i--; )
     switch (holds(x[i],y)) {
     case RT_FALSE:
       x[i] = x[--n_x]; break;
     case RT_TRUE:
       x[i] = x[--n_x]; c--; break;
     case RT_MAYBE:
       break;
     default:
       GECODE_NEVER;
     }
   x.size(n_x);
   if (c < 0)
     return ES_FAILED;
   if (c >= n_x)
     return ES_OK;
   // All views must be different
   if (c == 0)
     return post_false(home,x,y);
   (void) new (home) LqInt<VX,VY>(home,x,n_x-c+1,y,c);
   return ES_OK;
 }
Beispiel #5
0
 ExecStatus
 EqInt<VX,VY>::post(Home home, ViewArray<VX>& x, VY y, int c) {
   // Eliminate decided views
   int n_x = x.size();
   for (int i=n_x; i--; )
     switch (holds(x[i],y)) {
     case RT_FALSE:
       x[i] = x[--n_x]; break;
     case RT_TRUE:
       x[i] = x[--n_x]; c--; break;
     case RT_MAYBE:
       break;
     default:
       GECODE_NEVER;
     }
   x.size(n_x);
   // RHS too small or too large
   if ((c < 0) || (c > n_x))
     return ES_FAILED;
   // All views must be different
   if (c == 0)
     return post_false(home,x,y);
   // All views must be equal
   if (c == n_x)
     return post_true(home,x,y);
   // Compute how many subscriptions must be created
   int n_s = std::max(c,n_x-c)+1;
   assert(n_s <= n_x);
   (void) new (home) EqInt<VX,VY>(home,x,n_s,y,c);
   return ES_OK;
 }
Beispiel #6
0
  inline bool
  normalize(Space& home,
            ViewArray<View>& y,
            ViewArray<View>& x,
            bool& nofix) {

    int ys = y.size();
    for (int i = 1; i < ys; i++) {
      ModEvent me_lb = y[i].gq(home, y[i - 1].min());
      if (me_failed(me_lb))
        return false;
      nofix |= (me_modified(me_lb) && y[i - 1].min() != y[i].min());
    }

    for (int i = ys - 1; i--; ) {
      ModEvent me_ub = y[i].lq(home, y[i + 1].max());
      if (me_failed(me_ub))
        return false;
      nofix |= (me_modified(me_ub) && y[i + 1].max() != y[i].max());
    }

    int xs = x.size();
    for (int i = xs; i--; ) {
      ModEvent me = x[i].gq(home, y[0].min());
      if (me_failed(me))
        return false;
      nofix |= (me_modified(me) && x[i].min() != y[0].min());

      me = x[i].lq(home, y[xs - 1].max());
      if (me_failed(me))
        return false;
      nofix |= (me_modified(me) && x[i].max() != y[xs - 1].max());
    }
    return true;
  }
Beispiel #7
0
 inline ExecStatus
 Single<View>::post(Home home, ViewArray<View>& x, int s, int t) {
   {
     int alpha = 0;
     while ((alpha < x.size()) && !x[alpha].in(s))
       GECODE_ME_CHECK(x[alpha++].nq(home,t));
     x.drop_fst(alpha);
     if (x.size() == 0)
       return ES_OK;
   }
   // alpha has been normalized to 0
   int beta = 0, gamma = 0;
   GECODE_ME_CHECK(x[0].nq(home,t));
   do {
     gamma++;
   } while ((gamma < x.size()) && !assigned(x[gamma],t));
   do {
     beta++;
   } while ((beta < x.size()) && !x[beta].in(s));
   if (beta > gamma) {
     GECODE_ME_CHECK(x[0].eq(home, s));
     return ES_OK;
   }
   if (gamma < x.size())
     x.drop_lst(gamma);
   (void) new (home) Single<View>(home, x, s, t, beta, gamma);
   return ES_OK;
 }
Beispiel #8
0
  forceinline
  Incremental<View>::Incremental(Home home, ViewArray<View>& x,
                                 const TupleSet& t)
    : Base<View,false>(home,x,t), support_data(NULL),
      unassigned(x.size()), ac(home) {
    init_support(home);

    // Post advisors
    for (int i = x.size(); i--; )
      if (x[i].assigned()) {
        --unassigned;
      } else {
        x[i].subscribe(home,*new (home) SupportAdvisor(home,*this,ac,i));
      }

    Region r(home);

    // Add initial supports
    BitSet* dom = r.alloc<BitSet>(x.size());
    init_dom(home, dom);
    for (int i = x.size(); i--; )
      for (ViewValues<View> vv(x[i]); vv(); ++vv)
        find_support(home, dom, i, vv.val());

    // Work to be done or subsumption
    if (!w_support.empty() || !w_remove.empty() || (unassigned == 0))
      View::schedule(home,*this,
                     (unassigned != x.size()) ? ME_INT_VAL : ME_INT_DOM);
  }
Beispiel #9
0
 ExecStatus
 NaryEqv::post(Home home, ViewArray<BoolView>& x, int pm2) {
   int n = x.size();
   for (int i=n; i--; )
     if (x[i].assigned()) {
       pm2 ^= x[i].val();
       x[i] = x[--n];
     }
   if (n == 0)
     return (pm2 == 1) ? ES_OK : ES_FAILED;
   if (n == 1) {
     GECODE_ME_CHECK(x[0].eq(home,1^pm2));
     return ES_OK;
   }
   if (n == 2) {
     if (pm2 == 1) {
       return Bool::Eq<BoolView,BoolView>::post(home,x[0],x[1]);
     } else {
       NegBoolView n(x[1]);
       return Bool::Eq<BoolView,NegBoolView>::post(home,x[0],n);
     }
   }
   x.size(n);
   (void) new (home) NaryEqv(home,x,pm2);
   return ES_OK;
 }
Beispiel #10
0
 ExecStatus
 GqInt<VX,VY>::post(Home home, ViewArray<VX>& x, VY y, int c) {
   // Eliminate decided views
   int n_x = x.size();
   for (int i=n_x; i--; )
     switch (holds(x[i],y)) {
     case RT_FALSE:
       x[i] = x[--n_x]; break;
     case RT_TRUE:
       x[i] = x[--n_x]; c--; break;
     case RT_MAYBE:
       break;
     default:
       GECODE_NEVER;
     }
   x.size(n_x);
   // RHS too large
   if (n_x < c)
     return ES_FAILED;
   // Whatever the x[i] take for values, the inequality is subsumed
   if (c <= 0)
     return ES_OK;
   // All views must be equal
   if (c == n_x)
     return post_true(home,x,y);
   (void) new (home) GqInt<VX,VY>(home,x,c+1,y,c);
   return ES_OK;
 }
Beispiel #11
0
 ExecStatus
 Val<View>::post(Home home, ViewArray<View>& x) {
   if (x.size() == 2)
     return Rel::Nq<View>::post(home,x[0],x[1]);
   if (x.size() > 2)
     (void) new (home) Val<View>(home,x);
   return ES_OK;
 }
Beispiel #12
0
 forceinline ExecStatus
 post_true(Home home, ViewArray<VX>& x, VX y) {
   ViewArray<VX> z(home,x.size()+1);
   z[x.size()] = y;
   for (int i = x.size(); i--; )
     z[i] = x[i];
   return Rel::NaryEqDom<VX>::post(home,z);
 }
Beispiel #13
0
 inline void
 sort_tau(ViewArray<View>& x, ViewArray<View>& z, int tau[]) {
   if (Perm) {
     TupleMaxIncExt<View> ltmax(x,z);
     Support::quicksort(&(*tau), x.size(), ltmax);
   } else {
     TupleMaxInc<View> ltmax(x);
     Support::quicksort(&(*tau), x.size(), ltmax);
   }
 }
Beispiel #14
0
 forceinline void
 Prop<View>::add(Space& home, ValSet& vs, ViewArray<View>& x) {
   int n=x.size();
   for (int i=n; i--; )
     if (x[i].assigned()) {
       vs.add(home, x[i].val());
       x[i] = x[--n];
     }
   x.size(n);
 }
Beispiel #15
0
 // Copy constructor during cloning
 NoOverlap(Space& home, bool share, NoOverlap& p)
   : Propagator(home,share,p) {
   x.update(home,share,p.x);
   y.update(home,share,p.y);
   // Also copy width and height arrays
   w = home.alloc<int>(x.size());
   h = home.alloc<int>(y.size());
   for (int i=x.size(); i--; ) {
     w[i]=p.w[i]; h[i]=p.h[i];
   }
 }
Beispiel #16
0
 forceinline ExecStatus
 prune(Space& home, ViewArray<VX>& x, VX y) {
   if (x.size() == 0)
     return ES_OK;
   Region r(home);
   ViewRanges<VX>* rx = r.alloc<ViewRanges<VX> >(x.size());
   for (int i=x.size(); i--; )
     rx[i] = ViewRanges<VX>(x[i]);
   Iter::Ranges::NaryUnion u(r, rx, x.size());
   GECODE_ME_CHECK(y.inter_r(home, u, false));
   return ES_OK;
 }
Beispiel #17
0
  inline ExecStatus
  LqBool<VY>::post(Home home, ViewArray<BoolView>& x, VY y) {
    if (x.size() == 0) {
      GECODE_ME_CHECK(y.gq(home,0));
      return ES_OK;
    }

    x.unique(home);

    GECODE_ME_CHECK(y.gq(home,1));

    if (x.size() == 1)
      return ES_OK;

    if (y.max() == 1) {
      assert(y.assigned());
      ViewArray<BoolView> xc(home,x);
      return Bool::NaryEq<BoolView>::post(home,xc);
    }

    if (y.min() >= 2)
      return ES_OK;

    int n = x.size();
    int status = 0;
    for (int i=n; i--; )
      if (x[i].zero()) {
        if (status & VS_ONE) {
          GECODE_ME_CHECK(y.gq(home,2));
          return ES_OK;
        }
        x[i] = x[--n];
        status |= VS_ZERO;
      } else if (x[i].one()) {
        if (status & VS_ZERO) {
          GECODE_ME_CHECK(y.gq(home,2));
          return ES_OK;
        }
        x[i] = x[--n];
        status |= VS_ONE;
      }
    
    assert(status != (VS_ZERO | VS_ONE));
    if (n == 0) {
      assert((status != 0) && (y.min() >= 1));
      return ES_OK;
    }

    x.size(n);

    (void) new (home) LqBool<VY>(home,status,x,y);
    return ES_OK;
  }
 forceinline ExecStatus
 LinkMulti::post(Home home, ViewArray<BoolView>& x, IntView y, int o) {
   int n=x.size();
   GECODE_ME_CHECK(y.gq(home,o));
   GECODE_ME_CHECK(y.lq(home,o+n-1));
   assert(n > 0);
   if (n == 1) {
     GECODE_ME_CHECK(x[0].one(home));
     assert(y.val() == o);
   } else if (y.assigned()) {
     int j=y.val()-o;
     GECODE_ME_CHECK(x[j].one(home));
     for (int i=0; i<j; i++)
       GECODE_ME_CHECK(x[i].zero(home));
     for (int i=j+1; i<n; i++)
       GECODE_ME_CHECK(x[i].zero(home));
   } else {
     for (int i=n; i--; )
       if (x[i].one()) {
         for (int j=0; j<i; j++)
           GECODE_ME_CHECK(x[j].zero(home));
         for (int j=i+1; j<n; j++)
           GECODE_ME_CHECK(x[j].zero(home));
         GECODE_ME_CHECK(y.eq(home,o+i));
         return ES_OK;
       } else if (x[i].zero()) {
         GECODE_ME_CHECK(y.nq(home,o+i));
       }
     (void) new (home) LinkMulti(home,x,y,o);
   }
   return ES_OK;
 }
Beispiel #19
0
 forceinline ExecStatus
 ChannelBool<View>::post(Home home, ViewArray<Gecode::Int::BoolView>& x,
                         View y) {
   GECODE_ME_CHECK(y.intersect(home, 0, x.size()-1));
   (void) new (home) ChannelBool(home,x,y);
   return ES_OK;
 }
Beispiel #20
0
  ExecStatus
  SeqU::propagateSeqUnion(Space& home,
                          bool& modified, ViewArray<SetView>& x,
                          SetView& y) {
    Region r(home);
    GlbRanges<SetView>* XLBs = r.alloc<GlbRanges<SetView> >(x.size());
    for (int i=x.size(); i--; ){
      GlbRanges<SetView> lb(x[i]);
      XLBs[i]=lb;
    }
    Iter::Ranges::NaryAppend<GlbRanges<SetView> > u(XLBs,x.size());
    GECODE_ME_CHECK_MODIFIED(modified, y.includeI(home,u));

    GLBndSet before(home);
    for (int i=0; i<x.size(); i++) {
      LubRanges<SetView> xiub(x[i]);
      before.includeI(home, xiub);
      BndSetRanges beforeR(before);
      GlbRanges<SetView> ylb(y);
      Iter::Ranges::Diff<GlbRanges<SetView>, BndSetRanges> diff(ylb, beforeR);
      if (diff()) {
        GECODE_ME_CHECK_MODIFIED(modified, x[i].exclude(home, diff.min(),
                                                        Limits::max));
      }
    }
    before.dispose(home);

    GLBndSet after(home);
    for (int i=x.size(); i--; ) {
      LubRanges<SetView> xiub(x[i]);
      after.includeI(home, xiub);
      BndSetRanges afterR(after);
      GlbRanges<SetView> ylb(y);
      Iter::Ranges::Diff<GlbRanges<SetView>, BndSetRanges> diff(ylb, afterR);
      if (diff()) {
        int max = diff.max();
        for (; diff(); ++diff)
          max = diff.max();
        GECODE_ME_CHECK_MODIFIED(modified, x[i].exclude(home,
                                                        Limits::min,
                                                        max));
      }
    }
    after.dispose(home);

    return ES_FIX;
  }
Beispiel #21
0
inline void
computesccs(Space& home, ViewArray<View>& x, ViewArray<View>& y,
            int phi[], SccComponent sinfo[], int scclist[]) {

    // number of sccs is bounded by xs (number of x-nodes)
    int xs = x.size();
    Region r(home);
    Support::StaticStack<int,Region> cs(r,xs);

    //select an y node from the graph
    for (int j = 0; j < xs; j++) {
        int yjmin = y[j].min();    // the processed min
        while (!cs.empty() && x[phi[sinfo[cs.top()].rightmost]].max() < yjmin) {
            // the topmost scc cannot "reach" y_j or a node to the right of it
            cs.pop();
        }

        // a component has the form C(y-Node, matching x-Node)
        // C is a minimal scc in the oriented intersection graph
        // we only store y_j-Node, since \phi(j) gives the matching X-node
        int i     = phi[j];
        int ximin = x[i].min();
        while (!cs.empty() && ximin <= y[sinfo[cs.top()].rightmost].max()) {
            // y_j can "reach" cs.top() ,
            // i.e. component c can reach component cs.top()
            // merge c and cs.top() into new component
            int top = cs.top();
            // connecting
            sinfo[sinfo[j].leftmost].left        = top;
            sinfo[top].right                     = sinfo[j].leftmost;
            // moving leftmost
            sinfo[j].leftmost                    = sinfo[top].leftmost;
            // moving rightmost
            sinfo[sinfo[top].leftmost].rightmost = j;
            cs.pop();
        }
        cs.push(j);
    }
    cs.reset();


    // now we mark all components with the respective scc-number
    // labeling is bound by O(k) which is bound by O(n)

    for (int i = 0; i < xs; i++) {
        if (sinfo[i].left == i) { // only label variables in sccs
            int scc = sinfo[i].rightmost;
            int z   = i;
            //bound by the size of the largest scc = k
            while (sinfo[z].right != z) {
                sinfo[z].rightmost   = scc;
                scclist[phi[z]]      = scc;
                z                    = sinfo[z].right;
            }
            sinfo[z].rightmost     = scc;
            scclist[phi[z]]        = scc;
        }
    }
}
Beispiel #22
0
 // Post no-overlap propagator
 static ExecStatus post(Home home, 
                        ViewArray<IntView>& x, int w[], 
                        ViewArray<IntView>& y, int h[]) {
   // Only if there is something to propagate
   if (x.size() > 1)
     (void) new (home) NoOverlap(home,x,w,y,h);
   return ES_OK;
 }
 static ExecStatus post(Home home, ViewArray<IntView>& x, int s[], bool a[], int n, int m, int t, int sz) {
     if(DEBUG) { std::cerr << "p"; }
     // only post if there is something to propagate
     if(x.size() > 1) {
         (void) new (home) NonLinearity(home,x,s,a,n,m,t,sz);
     }
     return ES_OK;
 }
Beispiel #24
0
 forceinline ExecStatus
 post_false(Home home, ViewArray<VX>& x, const IntSet& y) {
   for (int i = x.size(); i--; ) {
     IntSetRanges ry(y);
     GECODE_ME_CHECK(x[i].minus_r(home,ry,false));
   }
   return ES_OK;
 }
Beispiel #25
0
  inline ExecStatus
  ReProp<View,rm>::post(Home home, ViewArray<View>& x, View y, BoolView b) {
    if (x.size() == 0) {
      if (rm != RM_PMI)
        GECODE_ME_CHECK(b.zero(home));
      return ES_OK;
    }

    x.unique(home);

    if (x.size() == 1)
      return Rel::ReEqDom<View,BoolView,rm>::post(home,x[0],y,b);

    if (x.same(home,y)) {
      if (rm != RM_IMP)
        GECODE_ME_CHECK(b.one(home));
      return ES_OK;
    }
    
    // Eliminate assigned views and store them into the value set
    ValSet vs;
    add(home, vs, x);

    switch (vs.compare(y)) {
    case Iter::Ranges::CS_SUBSET:
      if (rm != RM_IMP)
        GECODE_ME_CHECK(b.one(home));
      return ES_OK;
    case Iter::Ranges::CS_DISJOINT:
      if (x.size() == 0) {
        if (rm != RM_PMI)
          GECODE_ME_CHECK(b.zero(home));
        return ES_OK;
      }
      break;
    case Iter::Ranges::CS_NONE:
      break;
    default:
      GECODE_NEVER;
    }

    (void) new (home) ReProp<View,rm>(home, vs, x, y, b);
    return ES_OK;
  }
Beispiel #26
0
 inline void
 sort_sigma(Space& home, ViewArray<View>& x, ViewArray<View>& z) {
   if (Perm) {
     Region r(home);
     ViewPair<View>* xz = r.alloc<ViewPair<View> >(x.size());
     for (int i=x.size(); i--; ) {
       xz[i].x=x[i]; xz[i].z=z[i];
     }
     TupleMinIncExt<View> min_inc;
     Support::quicksort<ViewPair<View>,TupleMinIncExt<View> >
       (&xz[0], x.size(), min_inc);
     for (int i=x.size(); i--; ) {
       x[i]=xz[i].x; z[i]=xz[i].z;
     }
   } else {
     TupleMinInc<View> min_inc;
     Support::quicksort<View,TupleMinInc<View> >(&x[0], x.size(), min_inc);
   }
 }
Beispiel #27
0
 forceinline ExecStatus
 Incremental<View>::post(Home home, ViewArray<View>& x, const TupleSet& t) {
   // All variables in the correct domain
   for (int i = x.size(); i--; ) {
     GECODE_ME_CHECK(x[i].gq(home, t.min()));
     GECODE_ME_CHECK(x[i].lq(home, t.max()));
   }
   (void) new (home) Incremental<View>(home,x,t);
   return ES_OK;
 }
Beispiel #28
0
 forceinline bool
 ViewBase<VX,VY,VZ>::sharing(const ViewArray<VX>& x, 
                             const VY& y, const VZ& z) {
   if (shared(y,z))
     return true;
   for (int i = x.size(); i--; )
     if (shared(x[i],z))
       return true;
   return false;
 }
Beispiel #29
0
  inline ExecStatus
  LqInt<VY>::post(Home home, ViewArray<IntView>& x, VY y) {
    if (x.size() == 0) {
      GECODE_ME_CHECK(y.eq(home,0));
      return ES_OK;
    }

    x.unique(home);

    GECODE_ME_CHECK(y.gq(home,1));

    if (x.size() == 1)
      return ES_OK;

    if (y.max() == 1) {
      assert(y.assigned());
      return Rel::NaryEqDom<IntView>::post(home,x);
    }

    if (y.min() >= x.size())
      return ES_OK;
    
    // Eliminate assigned views and store them into the value set
    ValSet vs;
    int n = x.size();
    for (int i=n; i--; )
      if (x[i].assigned()) {
        vs.add(home, x[i].val());
        x[i] = x[--n];
      }

    GECODE_ME_CHECK(y.gq(home,vs.size()));

    if (n == 0) {
      assert(y.min() >= vs.size());
      return ES_OK;
    }

    x.size(n);

    (void) new (home) LqInt<VY>(home, vs, x, y);
    return ES_OK;
  }
Beispiel #30
0
 forceinline
 BoolBase<VY>::BoolBase(Home home,
                        int status0, ViewArray<BoolView>& x, VY y0)
   : Propagator(home), status(status0), c(home), y(y0) {
   y.subscribe(home,*this,PC_INT_BND);
   for (int i=x.size(); i--; ) {
     assert(!x[i].assigned());
     (void) new (home) ViewAdvisor<BoolView>(home, *this, c, x[i]);
   }
 }