Example #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;
 }
Example #2
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;
  }
Example #3
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;
  }
  inline ExecStatus
  EqInt<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);

    if (x.size() == 1) {
      GECODE_ME_CHECK(y.eq(home,1));
      return ES_OK;
    }

    GECODE_ME_CHECK(y.gq(home,1));
    GECODE_ME_CHECK(y.lq(home,x.size()));

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

    if (y.min() == x.size()) {
      assert(y.assigned());
      return Distinct::Dom<IntView>::post(home,x);
    }
    
    // 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()));
    GECODE_ME_CHECK(y.lq(home,n + vs.size()));

    if (n == 0) {
      assert(y.val() == vs.size());
      return ES_OK;
    }
    x.size(n);
    (void) new (home) EqInt<VY>(home, vs, x, y);
    return ES_OK;
  }
Example #5
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;
  }
Example #6
0
File: eq.hpp Project: Gecode/gecode
 ExecStatus
 NaryEq<View>::post(Home home, ViewArray<View>& x) {
   x.unique(home);
   if (x.size() == 2) {
     return Eq<View,View>::post(home,x[0],x[1]);
   } else if (x.size() > 2) {
     FloatNum l = x[0].min();
     FloatNum u = x[0].max();
     for (int i=x.size(); i-- > 1; ) {
       l = std::max(l,x[i].min());
       u = std::min(u,x[i].max());
     }
     for (int i=x.size(); i--; ) {
       GECODE_ME_CHECK(x[i].gq(home,l));
       GECODE_ME_CHECK(x[i].lq(home,u));
     }
     (void) new (home) NaryEq<View>(home,x);
   }
   return ES_OK;
 }