Пример #1
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;
  }
Пример #2
0
  ExecStatus
  Union<View0,View1,View2>::propagate(Space& home, const ModEventDelta& med) {
    // This propagator implements the constraint
    // x2 = x0 u x1

    bool x0ass = x0.assigned();
    bool x1ass = x1.assigned();
    bool x2ass = x2.assigned();

    ModEvent me0 = View0::me(med);
    ModEvent me1 = View1::me(med);
    ModEvent me2 = View2::me(med);

    bool x0ubmod = false;
    bool x1ubmod = false;
    bool modified = false;

    do {

      modified = false;
      do {
        // 4) lub(x2) <= lub(x0) u lub(x1)
        {
          LubRanges<View0> x0ub(x0);
          LubRanges<View1> x1ub(x1);
          Iter::Ranges::Union<LubRanges<View0>, LubRanges<View1> > u2(x0ub,x1ub);
          GECODE_ME_CHECK_MODIFIED(modified, x2.intersectI(home,u2) );
        }

        if (modified || Rel::testSetEventUB(me2) )
          {
            modified = false;
            // 5) x0 <= x2
            LubRanges<View2> x2ub1(x2);
            GECODE_ME_CHECK_MODIFIED(modified, x0.intersectI(home,x2ub1) );
            x0ubmod |= modified;

            // 6) x1 <= x2
            bool modified2=false;
            LubRanges<View2> x2ub2(x2);
            GECODE_ME_CHECK_MODIFIED(modified2, x1.intersectI(home,x2ub2) );
            x1ubmod |= modified2;
            modified |= modified2;
          }

      } while (modified);

      modified = false;
      do {
        bool modifiedOld = modified;
        modified = false;

        if (Rel::testSetEventLB(me2) || Rel::testSetEventUB(me0)
             || x0ubmod || modifiedOld)
          {
            // 1) glb(x0) \ lub(x1) <= glb(x2)
            GlbRanges<View2> x2lb(x2);
            LubRanges<View0> x0ub(x0);
            Iter::Ranges::Diff<GlbRanges<View2>, LubRanges<View0> >
              diff(x2lb, x0ub);
            GECODE_ME_CHECK_MODIFIED(modified, x1.includeI(home,diff) );
          }

        if (Rel::testSetEventLB(me2) || Rel::testSetEventUB(me1)
            || x1ubmod || modifiedOld)
          {
            // 2) glb(x0) \ lub(x2) <= glb(x1)
            GlbRanges<View2> x2lb(x2);
            LubRanges<View1> x1ub(x1);
            Iter::Ranges::Diff<GlbRanges<View2>, LubRanges<View1> >
              diff(x2lb, x1ub);
            GECODE_ME_CHECK_MODIFIED(modified, x0.includeI(home,diff) );
          }

         if (Rel::testSetEventLB(me0,me1) || modified)
          {
            //            modified = false;
            // 3) glb(x1) u glb(x2) <= glb(x0)
            GlbRanges<View0> x0lb(x0);
            GlbRanges<View1> x1lb(x1);
            Iter::Ranges::Union<GlbRanges<View0>, GlbRanges<View1> >
              u1(x0lb,x1lb);
            GECODE_ME_CHECK_MODIFIED(modified, x2.includeI(home,u1) );
          }

      } while(modified);

      modified = false;
      {
        // cardinality
        ExecStatus ret = unionCard(home,modified, x0, x1, x2);
        GECODE_ES_CHECK(ret);
      }

      if (x2.cardMax() == 0) {
        GECODE_ME_CHECK( x0.cardMax(home, 0) );
        GECODE_ME_CHECK( x1.cardMax(home, 0) );
        return home.ES_SUBSUMED(*this);
      }

      if (x0.cardMax() == 0)
        GECODE_REWRITE(*this,(Rel::Eq<View1,View2>::post(home(*this),x1,x2)));
      if (x1.cardMax() == 0)
        GECODE_REWRITE(*this,(Rel::Eq<View0,View2>::post(home(*this),x0,x2)));

    } while(modified);

    if (shared(x0,x1,x2)) {
      return (x0ass && x1ass && x2ass) ? home.ES_SUBSUMED(*this) : ES_NOFIX;
    } else {
      if (x0ass && x1ass && x2ass)
        return home.ES_SUBSUMED(*this);
      if (x0ass != x0.assigned() ||
          x1ass != x1.assigned() ||
          x2ass != x2.assigned()) {
        return ES_NOFIX;
      } else {
         return ES_FIX;
      }
    }
  }
Пример #3
0
  ExecStatus
  SuperOfInter<View0,View1,View2>::propagate(Space& home, const ModEventDelta& med) {

    bool allassigned = x0.assigned() && x1.assigned() && x2.assigned();

    ModEvent me0 = View0::me(med);
    ModEvent me1 = View1::me(med);
    ModEvent me2 = View2::me(med);

    bool modified = false;

    do {
      // glb(x2) >= glb(x0) ^ glb(x1)
      if ( modified || Rel::testSetEventLB(me0,me1)) {
        GlbRanges<View0> lb0(x0);
        GlbRanges<View1> lb1(x1);
        Iter::Ranges::Inter<GlbRanges<View0>,GlbRanges<View1> >
          is(lb0, lb1);

        GECODE_ME_CHECK_MODIFIED(modified,x2.includeI(home,is));
      }

      // lub(x0) -= glb(x1)-lub(x2)
      // lub(x1) -= glb(x0)-lub(x2)
      if ( modified || Rel::testSetEventAnyB(me0,me1,me2)) {
         modified = false;
        GlbRanges<View1> lb12(x1);
        LubRanges<View2> ub22(x2);
        Iter::Ranges::Diff<GlbRanges<View1>, LubRanges<View2> >
          diff1(lb12, ub22);

        GECODE_ME_CHECK_MODIFIED(modified, x0.excludeI(home,diff1));

        GlbRanges<View0> lb01(x0);
        LubRanges<View2> ub23(x2);
        Iter::Ranges::Diff<GlbRanges<View0>, LubRanges<View2> >
          diff2(lb01, ub23);

        GECODE_ME_CHECK_MODIFIED(modified, x1.excludeI(home,diff2));
      } else {
         modified = false;
      }

      // Cardinality propagation
      if ( modified ||
            Rel::testSetEventCard(me0,me1,me2) ||
           Rel::testSetEventUB(me0,me1)
           ) {

        LubRanges<View0> ub0(x0);
        LubRanges<View1> ub1(x1);
        Iter::Ranges::Union<LubRanges<View0>, LubRanges<View1> > u(ub0,ub1);

        unsigned int m = Iter::Ranges::size(u);

        if (m < x0.cardMin() + x1.cardMin()) {
          GECODE_ME_CHECK_MODIFIED(modified,
                            x2.cardMin( home,
                                        x0.cardMin()+x1.cardMin() - m ) );
        }
        if (m + x2.cardMax() > x1.cardMin()) {
          GECODE_ME_CHECK_MODIFIED(modified,
                            x0.cardMax( home,
                                        m+x2.cardMax()-x1.cardMin() )  );
        }
        if (m + x2.cardMax() > x0.cardMin()) {
          GECODE_ME_CHECK_MODIFIED(modified,
                            x1.cardMax( home,
                                        m+x2.cardMax()-x0.cardMin() )  );
        }
      }
    } while (modified);


    if (shared(x0,x1,x2)) {
      if (allassigned) {
        return home.ES_SUBSUMED(*this);
      } else {
        return ES_NOFIX;
      }
    } else {
      if (x0.assigned() + x1.assigned() + x2.assigned() >= 2) {
         return home.ES_SUBSUMED(*this);
      } else {
        return ES_FIX;
      }
    }

  }
Пример #4
0
  ExecStatus
  Match<View>::propagate(Space& home, const ModEventDelta&) {

    int xs_size = xs.size();

    bool loopFlag;

    do {
      loopFlag = false;

      // Order int vars in xs
      GECODE_ME_CHECK(xs[0].gq(home,x0.lubMin()));
      for (int i=xs_size-1; i--; ) {
        GECODE_ME_CHECK_MODIFIED(loopFlag, xs[i+1].gq(home,xs[i].min() + 1));
      }

      GECODE_ME_CHECK_MODIFIED(loopFlag, xs[xs_size-1].lq(home,x0.lubMax()));
      for (int i=xs_size-2; i--; ) {
        GECODE_ME_CHECK_MODIFIED(loopFlag, xs[i].lq(home,xs[i+1].max() - 1));
      }

      // if y from xs is assigned, add to glb(x0)
      for (int i=xs_size; i--; ) {
        if (xs[i].assigned()) {
          GECODE_ME_CHECK_MODIFIED(loopFlag, x0.include(home,xs[i].val()));
        }
      }

      // intersect every y in xs with lub(x0)
      for (int i=xs_size; i--; ) {
        LubRanges<View> ub(x0);
        GECODE_ME_CHECK_MODIFIED(loopFlag, xs[i].inter_r(home,ub,false));
      }

      // remove gaps between vars in xs from lub(x0)
      GECODE_ME_CHECK_MODIFIED(loopFlag,
                        x0.exclude(home,Limits::min,xs[0].min()-1));
      GECODE_ME_CHECK_MODIFIED(loopFlag,
                        x0.exclude(home,xs[xs_size-1].max()+1,
                                   Limits::max));

      for (int i=xs_size-1; i--; ) {
        int start = xs[i].max() + 1;
        int end   = xs[i+1].min() - 1;
        if (start<=end) {
          GECODE_ME_CHECK_MODIFIED(loopFlag, x0.exclude(home,start,end));
        }
      }

      // try to assign vars in xs from glb(x0)
      if (x0.glbSize()>0) {

        LubRanges<View> ub(x0);
        Iter::Ranges::ToValues<LubRanges<View> > ubv(ub);
        GlbRanges<View> lb(x0);
        Iter::Ranges::ToValues<GlbRanges<View> > lbv(lb);

        int i=0;
        for (; ubv() && lbv() && ubv.val()==lbv.val();
            ++ubv, ++lbv, i++) {
          GECODE_ME_CHECK_MODIFIED(loopFlag, xs[i].eq(home,lbv.val()));
        }

        if (i<xs_size-1 && x0.lubMax()==x0.glbMax()) {
          LubRanges<View> lbx0(x0);
          GlbRanges<View> ubx0(x0);
          Iter::Ranges::Inter<LubRanges<View>,GlbRanges<View> >
            inter(lbx0, ubx0);

          int to = x0.glbMax();
          int from = to;
          while (inter()) {
            from = inter.min();
            ++inter;
          }

          int i=xs_size-1;
          for (int j=to; j>=from;j--,i--) {
            GECODE_ME_CHECK_MODIFIED(loopFlag, xs[i].eq(home,j));
          }
        }
      }

    } while (loopFlag);

    for (int i=xs_size; i--; )
      if (!xs[i].assigned())
        return ES_FIX;
    return home.ES_SUBSUMED(*this);
  }