Пример #1
0
  void
  extensional(Home home, const BoolVarArgs& x, const TupleSet& t,
              IntPropLevel ipl) {
    using namespace Int;
    if (!t.finalized())
      throw NotYetFinalized("Int::extensional");
    if (t.arity() != x.size())
      throw ArgumentSizeMismatch("Int::extensional");
    GECODE_POST;

    if (t.tuples()==0) {
      if (x.size()!=0) {
        home.fail();
      }
      return;
    }

    // Construct view array
    ViewArray<BoolView> xv(home,x);
    if (ipl & IPL_MEMORY) {
      if (x.same(home)) {
        GECODE_ES_FAIL((Extensional::Basic<BoolView,true>
                             ::post(home,xv,t)));
      } else {
        GECODE_ES_FAIL((Extensional::Basic<BoolView,false>
                             ::post(home,xv,t)));
      }
    } else {
      GECODE_ES_FAIL((Extensional::Incremental<BoolView>
                           ::post(home,xv,t)));
    }
  }
Пример #2
0
 void
 unary(Home home, const IntVarArgs& s, const IntVarArgs& p, 
       const IntVarArgs& e, const BoolVarArgs& m, IntConLevel icl) {
   using namespace Gecode::Int;
   using namespace Gecode::Int::Unary;
   if ((s.size() != p.size()) || (s.size() != m.size()) ||
       (s.size() != e.size()))
     throw Int::ArgumentSizeMismatch("Int::unary");
   if (home.failed()) return;
   for (int i=p.size(); i--; ) {
     rel(home, p[i], IRT_GQ, 0);
   }
   bool allMandatory = true;
   for (int i=m.size(); i--;) {
     if (!m[i].one()) {
       allMandatory = false;
       break;
     }
   }
   if (allMandatory) {
     unary(home,s,p,e,icl);
   } else {
     TaskArray<OptFlexTask> t(home,s.size());
     for (int i=s.size(); i--; )
       t[i].init(s[i],p[i],e[i],m[i]);
     GECODE_ES_FAIL(OptProp<OptFlexTask>::post(home,t));
   }
 }
Пример #3
0
 void
 unary(Home home, const IntVarArgs& s, const IntArgs& p, 
       const BoolVarArgs& m, IntConLevel icl) {
   using namespace Gecode::Int;
   using namespace Gecode::Int::Unary;
   if (s.same(home))
     throw Int::ArgumentSame("Int::unary");
   if ((s.size() != p.size()) || (s.size() != m.size()))
     throw Int::ArgumentSizeMismatch("Int::unary");
   for (int i=p.size(); i--; ) {
     Int::Limits::nonnegative(p[i],"Int::unary");
     Int::Limits::check(static_cast<double>(s[i].max()) + p[i],
                        "Int::unary");
   }
   bool allMandatory = true;
   for (int i=m.size(); i--;) {
     if (!m[i].one()) {
       allMandatory = false;
       break;
     }
   }
   if (allMandatory) {
     unary(home,s,p,icl);
   } else {
     if (home.failed()) return;
     TaskArray<OptFixPTask> t(home,s.size());
     for (int i=s.size(); i--; )
       t[i].init(s[i],p[i],m[i]);
     GECODE_ES_FAIL(OptProp<OptFixPTask>::post(home,t));
   }
 }
Пример #4
0
  void
  extensional(Home home, const BoolVarArgs& x, const TupleSet& t,
              ExtensionalPropKind epk, IntConLevel) {
    using namespace Int;
    if (!t.finalized())
      throw NotYetFinalized("Int::extensional");
    if (t.arity() != x.size())
      throw ArgumentSizeMismatch("Int::extensional");
    if (home.failed()) return;

    // Construct view array
    ViewArray<BoolView> xv(home,x);
    switch (epk) {
    case EPK_SPEED:
      GECODE_ES_FAIL((Extensional::Incremental<BoolView>
                           ::post(home,xv,t)));
      break;
    default:
      if (x.same(home)) {
        GECODE_ES_FAIL((Extensional::Basic<BoolView,true>
                             ::post(home,xv,t)));
      } else {
        GECODE_ES_FAIL((Extensional::Basic<BoolView,false>
                             ::post(home,xv,t)));
      }
      break;
    }
  }
Пример #5
0
 BoolExpr
 element(const BoolVarArgs& b, const LinExpr& idx) {
   BElementExpr* be = new BElementExpr(b.size());
   for (int i=b.size(); i--;)
     new (&be->a[i]) BoolExpr(b[i]);
   be->idx = idx;
   return BoolExpr(be);
 }
Пример #6
0
 void
 cumulative(Home home, Cap c, const TaskTypeArgs& t,
            const IntVarArgs& s, const IntArgs& p, const IntArgs& u,
            const BoolVarArgs& m, IntConLevel icl) {
   using namespace Gecode::Int;
   using namespace Gecode::Int::Cumulative;
   if ((s.size() != p.size()) || (s.size() != u.size()) ||
       (s.size() != t.size()) || (s.size() != m.size()))
     throw Int::ArgumentSizeMismatch("Int::cumulative");
   long long int w = 0;
   for (int i=p.size(); i--; ) {
     Limits::nonnegative(p[i],"Int::cumulative");
     Limits::nonnegative(u[i],"Int::cumulative");
     Limits::check(static_cast<long long int>(s[i].max()) + p[i],
                   "Int::cumulative");
     mul_check(p[i],u[i]);
     w += s[i].width();
   }
   mul_check(c.max(),w,s.size());
   if (home.failed()) return;
   
   bool allMandatory = true;
   for (int i=m.size(); i--;) {
     if (!m[i].one()) {
       allMandatory = false;
       break;
     }
   }
   if (allMandatory) {
     cumulative(home,c,t,s,p,u,icl);
   } else {
     bool fixp = true;
     for (int i=t.size(); i--;)
       if (t[i] != TT_FIXP) {
         fixp = false; break;
       }
     int nonOptionals = 0;
     for (unsigned int i=u.size(); i--;)
       if (u[i]>0) nonOptionals++;
     if (fixp) {
       TaskArray<OptFixPTask> tasks(home,nonOptionals);
       int cur = 0;
       for (int i=0; i<s.size(); i++)
         if (u[i]>0)
           tasks[cur++].init(s[i],p[i],u[i],m[i]);
       GECODE_ES_FAIL((OptProp<OptFixPTask,Cap>::post(home,c,tasks)));
     } else {
       TaskArray<OptFixPSETask> tasks(home,nonOptionals);
       int cur = 0;
       for (int i=s.size(); i--;)
         if (u[i]>0)
           tasks[cur++].init(t[i],s[i],p[i],u[i],m[i]);
       GECODE_ES_FAIL((OptProp<OptFixPSETask,Cap>::post(home,c,tasks)));
     }
   }
 }
Пример #7
0
  void
  nooverlap(Home home, 
            const IntVarArgs& x0, const IntVarArgs& w, const IntVarArgs& x1,
            const IntVarArgs& y0, const IntVarArgs& h, const IntVarArgs& y1,
            const BoolVarArgs& m,
            IntConLevel) {
    using namespace Int;
    using namespace NoOverlap;
    if ((x0.size() != w.size())  || (x0.size() != x1.size()) || 
        (x0.size() != y0.size()) || (x0.size() != h.size()) || 
        (x0.size() != y1.size()) || (x0.size() != m.size()))
      throw ArgumentSizeMismatch("Int::nooverlap");
    if (x0.same(home) || w.same(home) || x1.same(home) ||
        y0.same(home) || h.same(home) || y1.same(home) ||
        m.same(home))
      throw ArgumentSame("Int::nooverlap");
    if (home.failed()) return;

    for (int i=x0.size(); i--; ) {
      GECODE_ME_FAIL(IntView(w[i]).gq(home,0));
      GECODE_ME_FAIL(IntView(h[i]).gq(home,0));
    }

    if (w.assigned() && h.assigned()) {
      IntArgs wc(x0.size()), hc(x0.size());
      for (int i=x0.size(); i--; ) {
        wc[i] = w[i].val();
        hc[i] = h[i].val();
      }
      nooverlap(home, x0, wc, y0, hc, m);
    } else if (optional(m)) {
      OptBox<FlexDim,2>* b 
        = static_cast<Space&>(home).alloc<OptBox<FlexDim,2> >(x0.size());
      for (int i=x0.size(); i--; ) {
        b[i][0] = FlexDim(x0[i],w[i],x1[i]);
        b[i][1] = FlexDim(y0[i],h[i],y1[i]);
        b[i].optional(m[i]);
      }
      GECODE_ES_FAIL((NoOverlap::OptProp<FlexDim,2>::post(home,b,x0.size())));
    } else {
      ManBox<FlexDim,2>* b 
        = static_cast<Space&>(home).alloc<ManBox<FlexDim,2> >(x0.size());
      int n = 0;
      for (int i=0; i<x0.size(); i++)
        if (m[i].one()) {
          b[n][0] = FlexDim(x0[i],w[i],x1[i]);
          b[n][1] = FlexDim(y0[i],h[i],y1[i]);
          n++;
        }
      GECODE_ES_FAIL((NoOverlap::ManProp<FlexDim,2>::post(home,b,n)));
    }
  }
Пример #8
0
 void
 dom(Home home, const BoolVarArgs& x, const BoolVarArgs& d, IntConLevel) {
   using namespace Int;    
   if (x.size() != d.size())
     throw ArgumentSizeMismatch("Int::dom");
   for (int i=x.size(); i--; ) {
     if (home.failed()) return;
     if (d[i].one())
       GECODE_ME_FAIL(BoolView(x[i]).one(home));
     else if (d[i].zero())
       GECODE_ME_FAIL(BoolView(x[i]).zero(home));
   }
 }
Пример #9
0
 LinExpr::LinExpr(const BoolVarArgs& x) :
   n(new Node) {
   n->n_int = 0;
   n->n_bool = x.size();
   n->t = NT_SUM_BOOL;
   n->l = n->r = NULL;
   if (x.size() > 0) {
     n->sum.tb = heap.alloc<Int::Linear::Term<Int::BoolView> >(x.size());
     for (int i=x.size(); i--; ) {
       n->sum.tb[i].x = x[i];
       n->sum.tb[i].a = 1;
     }
   }
 }
Пример #10
0
 bool
 optional(const BoolVarArgs& m) {
   for (int i=m.size(); i--; )
     if (m[i].none())
       return true;
   return false;
 }
Пример #11
0
 LinExpr::LinExpr(const IntArgs& a, const BoolVarArgs& x) :
   n(new Node) {
   if (a.size() != x.size())
     throw Int::ArgumentSizeMismatch("MiniModel::LinExpr");
   n->n_int = 0;
   n->n_bool = x.size();
   n->t = NT_SUM_BOOL;
   n->l = n->r = NULL;
   if (x.size() > 0) {
     n->sum.tb = heap.alloc<Int::Linear::Term<Int::BoolView> >(x.size());
     for (int i=x.size(); i--; ) {
       n->sum.tb[i].x = x[i];
       n->sum.tb[i].a = a[i];
     }
   }
 }
Пример #12
0
 void
 nooverlap(Home home, 
           const IntVarArgs& x, const IntArgs& w, 
           const IntVarArgs& y, const IntArgs& h,
           const BoolVarArgs& m,
           IntConLevel) {
   using namespace Int;
   using namespace NoOverlap;
   if (x.same(home) || y.same(home) || m.same(home))
     throw ArgumentSame("Int::nooverlap");
   if ((x.size() != w.size()) || (x.size() != y.size()) ||
       (x.size() != h.size()) || (x.size() != m.size()))
     throw ArgumentSizeMismatch("Int::nooverlap");      
   for (int i=x.size(); i--; ) {
     Limits::nonnegative(w[i],"Int::nooverlap");
     Limits::nonnegative(h[i],"Int::nooverlap");
     Limits::check(static_cast<double>(x[i].max()) + w[i],
                   "Int::nooverlap");
     Limits::check(static_cast<double>(y[i].max()) + h[i],
                   "Int::nooverlap");
   }
   if (home.failed()) return;
   
   if (optional(m)) {
     OptBox<FixDim,2>* b 
       = static_cast<Space&>(home).alloc<OptBox<FixDim,2> >(x.size());
     for (int i=x.size(); i--; ) {
       b[i][0] = FixDim(x[i],w[i]);
       b[i][1] = FixDim(y[i],h[i]);
       b[i].optional(m[i]);
     }
     GECODE_ES_FAIL((NoOverlap::OptProp<FixDim,2>::post(home,b,x.size())));
   } else {
     ManBox<FixDim,2>* b 
       = static_cast<Space&>(home).alloc<ManBox<FixDim,2> >(x.size());
     int n = 0;
     for (int i=0; i<x.size(); i++)
       if (m[i].one()) {
         b[n][0] = FixDim(x[i],w[i]);
         b[n][1] = FixDim(y[i],h[i]);
         n++;
       }
     GECODE_ES_FAIL((NoOverlap::ManProp<FixDim,2>::post(home,b,n)));
   }
 }
Пример #13
0
 void
 extensional(Home home, const BoolVarArgs& x, DFA dfa,
             IntPropLevel) {
   using namespace Int;
   if (x.same(home))
     throw ArgumentSame("Int::extensional");
   GECODE_POST;
   GECODE_ES_FAIL(Extensional::post_lgp(home,x,dfa));
 }
Пример #14
0
 void
 extensional(Home home, const BoolVarArgs& x, DFA dfa,
             IntConLevel) {
   using namespace Int;
   if (x.same(home))
     throw ArgumentSame("Int::extensional");
   if (home.failed()) return;
   GECODE_ES_FAIL(Extensional::post_lgp(home,x,dfa));
 }
Пример #15
0
void
linear(Home home,
       const IntArgs& a, const BoolVarArgs& x, IntRelType irt, IntVar y,
       Reify r, IntPropLevel ipl) {
    if (a.size() != x.size())
        throw ArgumentSizeMismatch("Int::linear");
    GECODE_POST;

    int n=x.size();
    Region re(home);
    Linear::Term<BoolView>* t = re.alloc<Linear::Term<BoolView> >(n);
    for (int i=n; i--; ) {
        t[i].a=a[i];
        t[i].x=x[i];
    }

    Linear::post(home,t,n,irt,y,r,ipl);
}
Пример #16
0
  void
  cumulative(Home home, Cap c, const IntVarArgs& s, const IntVarArgs& p,
             const IntVarArgs& e, const IntArgs& u, const BoolVarArgs& m, 
             IntConLevel icl) {
    using namespace Gecode::Int;
    using namespace Gecode::Int::Cumulative;
    if ((s.size() != p.size()) || (s.size() != u.size()) ||
        (s.size() != e.size()) || (s.size() != m.size()))
      throw Int::ArgumentSizeMismatch("Int::cumulative");
    for (int i=p.size(); i--; ) {
      rel(home, p[i], IRT_GQ, 0);
    }
    long long int w = 0;
    for (int i=p.size(); i--; ) {
      Limits::nonnegative(u[i],"Int::cumulative");
      Limits::check(static_cast<long long int>(s[i].max()) + p[i].max(),
                    "Int::cumulative");
      mul_check(p[i].max(),u[i]);
      w += s[i].width();
    }
    mul_check(c.max(),w,s.size());
    if (home.failed()) return;

    bool allMandatory = true;
    for (int i=m.size(); i--;) {
      if (!m[i].one()) {
        allMandatory = false;
        break;
      }
    }
    if (allMandatory) {
      cumulative(home,c,s,p,e,u,icl);
    } else {
      int nonOptionals = 0;
      for (unsigned int i=u.size(); i--;)
        if (u[i]>0) nonOptionals++;
      TaskArray<OptFlexTask> t(home,nonOptionals);
      int cur = 0;
      for (int i=s.size(); i--; )
        if (u[i]>0)
          t[cur++].init(s[i],p[i],e[i],u[i],m[i]);
      GECODE_ES_FAIL((OptProp<OptFlexTask,Cap>::post(home,c,t)));
    }
  }
Пример #17
0
 void
 unary(Home home, const TaskTypeArgs& t,
       const IntVarArgs& flex, const IntArgs& fix, const BoolVarArgs& m, 
       IntConLevel icl) {
   using namespace Gecode::Int;
   using namespace Gecode::Int::Unary;
   if ((flex.size() != fix.size()) || (flex.size() != t.size()) ||
       (flex.size() != m.size()))
     throw Int::ArgumentSizeMismatch("Int::unary");
   bool fixp = true;
   for (int i=fix.size(); i--; ) {
     if (t[i] == TT_FIXP) {
       Int::Limits::nonnegative(fix[i],"Int::unary");
     } else {
       fixp = false;
       Int::Limits::check(fix[i],"Int::unary");
     }
     Int::Limits::check(static_cast<double>(flex[i].max()) + fix[i],
                        "Int::unary");
   }
   if (home.failed()) return;
   bool allMandatory = true;
   for (int i=m.size(); i--;) {
     if (!m[i].one()) {
       allMandatory = false;
       break;
     }
   }
   if (allMandatory) {
     unary(home,t,flex,fix,icl);
   } else {
     if (fixp) {
       TaskArray<OptFixPTask> tasks(home,flex.size());
       for (int i=flex.size(); i--; )
         tasks[i].init(flex[i],fix[i],m[i]);
       GECODE_ES_FAIL(OptProp<OptFixPTask>::post(home,tasks));
     } else {
       TaskArray<OptFixPSETask> tasks(home,flex.size());
       for (int i=flex.size(); i--;)
         tasks[i].init(t[i],flex[i],fix[i],m[i]);
       GECODE_ES_FAIL(OptProp<OptFixPSETask>::post(home,tasks));
     }
   }
 }
Пример #18
0
  void
  distinct(Home home, const BoolVarArgs& b, const IntVarArgs& x,
           IntPropLevel ipl) {
    using namespace Int;
    if (x.same(home))
      throw ArgumentSame("Int::distinct");
    if (b.size() != x.size())
      throw ArgumentSizeMismatch("Int::distinct");
    GECODE_POST;

    int n = x.size();
    int min = Limits::max;
    int max = Limits::min;
    int m = 0;
    for (int i=n; i--; )
      if (!b[i].zero()) {
        min = std::min(min,x[i].min());
        max = std::max(max,x[i].max());
        m++;
      }

    if (m < 2)
      return;

    int start;
    if (max < Limits::max-m)
      start = max+1;
    else if (min > Limits::min+m)
      start = min-(m+1);
    else
      throw OutOfLimits("Int::distinct");

    ViewArray<IntView> y(home,m);
    int j = 0;
    for (int i=n; i--; )
      if (b[i].one()) {
        y[j] = x[i]; j++;
      } else if (b[i].none()) {
        y[j] = IntVar(home, Limits::min, Limits::max);
        GECODE_ES_FAIL((Bool::IteDom<IntView,ConstIntView,IntView>::post
                        (home, b[i], x[i], start+j, y[j])));
        j++;
      }
    assert(j == m);

    switch (vbd(ipl)) {
    case IPL_BND:
      GECODE_ES_FAIL(Distinct::Bnd<IntView>::post(home,y));
      break;
    case IPL_DOM:
      GECODE_ES_FAIL(Distinct::Dom<IntView>::post(home,y));
      break;
    default:
      GECODE_ES_FAIL(Distinct::Val<IntView>::post(home,y));
    }
  }
Пример #19
0
 void
 element(Home home, const BoolVarArgs& a, 
         IntVar x, int w, IntVar y, int h, BoolVar z,
         IntConLevel icl) {
   using namespace Int;
   if (a.size() != w*h)
     throw Int::ArgumentSizeMismatch("Int::element");
   if (home.failed()) return;
   element(home, a, pair(home,x,w,y,h), z, icl);
 }
Пример #20
0
 void
 channel(Home home, const BoolVarArgs& x, IntVar y, int o,
         IntConLevel) {
   using namespace Int;
   if (x.same(home))
     throw ArgumentSame("Int::channel");
   Limits::check(o,"Int::channel");
   if (home.failed()) return;
   ViewArray<BoolView> xv(home,x);
   GECODE_ES_FAIL(Channel::LinkMulti::post(home,xv,y,o));
 }
Пример #21
0
 void
 element(Home home, const BoolVarArgs& c, IntVar x0, BoolVar x1,
         IntConLevel) {
   using namespace Int;
   if (c.size() == 0)
     throw TooFewArguments("Int::element");
   if (home.failed()) return;
   IdxViewArray<BoolView> iv(home,c);
   GECODE_ES_FAIL((Element::ViewBnd<BoolView,IntView,BoolView>
                        ::post(home,iv,x0,x1)));
 }
Пример #22
0
void
linear(Home home,
       const IntArgs& a, const BoolVarArgs& x, IntRelType irt, IntVar y,
       IntPropLevel ipl) {
    if (a.size() != x.size())
        throw ArgumentSizeMismatch("Int::linear");

    GECODE_POST;

    int n=x.size();
    Region re(home);
    Linear::Term<BoolView>* t =
        re.alloc<Linear::Term<BoolView> >(n);
    for (int i=n; i--; ) {
        t[i].a=a[i];
        t[i].x=x[i];
    }
    int min, max;
    estimate(t,n,0,min,max);
    IntView v(y);
    switch (irt) {
    case IRT_EQ:
        GECODE_ME_FAIL(v.gq(home,min));
        GECODE_ME_FAIL(v.lq(home,max));
        break;
    case IRT_GQ:
        GECODE_ME_FAIL(v.lq(home,max));
        break;
    case IRT_LQ:
        GECODE_ME_FAIL(v.gq(home,min));
        break;
    default:
        ;
    }
    if (home.failed()) return;
    Linear::post(home,t,n,irt,y,0,ipl);
}
Пример #23
0
void
linear(Home home, const BoolVarArgs& x, IntRelType irt, IntVar y,
       IntPropLevel ipl) {
    GECODE_POST;

    int n=x.size();
    Region re(home);
    Linear::Term<BoolView>* t = re.alloc<Linear::Term<BoolView> >(n);
    for (int i=n; i--; ) {
        t[i].a=1;
        t[i].x=x[i];
    }

    Linear::post(home,t,n,irt,y,0,ipl);
}
Пример #24
0
  void
  sequence(Home home, const BoolVarArgs& x, const IntSet& s, 
           int q, int l, int u, IntConLevel) {
    if ((s.min() < 0) || (s.max() > 1))
      throw NotZeroOne("Int::sequence");

    if (x.size() == 0)
      throw TooFewArguments("Int::sequence");

    Limits::check(q,"Int::sequence");
    Limits::check(l,"Int::sequence");
    Limits::check(u,"Int::sequence");

    if (x.same(home))
      throw ArgumentSame("Int::sequence");

    if ((q < 1) || (q > x.size()))
      throw OutOfLimits("Int::sequence");

    if (home.failed())
      return;

    // Normalize l and u
    l=std::max(0,l); u=std::min(q,u);

    // Lower bound of values taken can never exceed upper bound
    if (u < l) {
      home.fail(); return;
    }

    // Already subsumed as any number of values taken is okay
    if ((0 == l) && (q == u)) 
      return;

    // Check whether the set is {0,1}, then the number of values taken is q
    if ((s.min() == 0) && (s.max() == 1)) {
      if ((l > 0) || (u < q))
        home.failed();
      return;
    }
    assert(s.min() == s.max());

    // All variables must take a value in s
    if (l == q) {
      if (s.min() == 0) {
        for (int i=x.size(); i--; ) {
          BoolView xv(x[i]); GECODE_ME_FAIL(xv.zero(home));
        }
      } else {
        assert(s.min() == 1);
        for (int i=x.size(); i--; ) {
          BoolView xv(x[i]); GECODE_ME_FAIL(xv.one(home));
        }
      }
      return;
    }

    // No variable can take a value in s
    if (0 == u) {
      if (s.min() == 0) {
        for (int i=x.size(); i--; ) {
          BoolView xv(x[i]); GECODE_ME_FAIL(xv.one(home));
        }
      } else {
        assert(s.min() == 1);
        for (int i=x.size(); i--; ) {
          BoolView xv(x[i]); GECODE_ME_FAIL(xv.zero(home));
        }
      }
      return;
    }

    ViewArray<BoolView> xv(home,x);

    GECODE_ES_FAIL(
                   (Sequence::Sequence<BoolView,int>::post
                    (home,xv,s.min(),q,l,u)));
  }
Пример #25
0
//@+node:gcross.20101224191604.2770: ** Functions
//@+node:gcross.20110114154616.2017: *3* channelMatrix
IntMatrix channelMatrix(Space& space, const BoolMatrix& matrix) {
    BoolVarArgs vars = matrix.get_array();
    IntVarArgs vars_as_ints(space,vars.size(),0,1);
    BOOST_FOREACH(const unsigned int i, irange(0u,(unsigned int)vars.size())) { channel(space,vars[i],vars_as_ints[i]); }
    return IntMatrix(vars_as_ints,matrix.width(),matrix.height());
}