ExecStatus ElementUnionConst<SView,RView>::propagate(Space& home, const ModEventDelta&) { Region r(home); bool* stillSelected = r.alloc<bool>(n_iv); bool loopVar; do { loopVar = false; for (int i=n_iv; i--;) stillSelected[i] = false; // Cache the upper bound iterator, as we have to // modify the upper bound while iterating LubRanges<RView> x1ub(x1); Iter::Ranges::Cache x1ubc(r,x1ub); Iter::Ranges::ToValues<Iter::Ranges::Cache> vx1ub(x1ubc); GlbRanges<RView> x1lb(x1); Iter::Ranges::Cache x1lbc(r,x1lb); Iter::Ranges::ToValues<Iter::Ranges::Cache> vx1(x1lbc); // In the first iteration, compute in before[i] the union // of all the upper bounds of the x_i. At the same time, // exclude inconsistent x_i from x1. GLBndSet sofarBefore(home); LUBndSet selectedInter(home, IntSet (Limits::min, Limits::max)); GLBndSet* before = static_cast<GLBndSet*>(r.ralloc(sizeof(GLBndSet)*n_iv)); unsigned int maxCard = 0; unsigned int minCard = Limits::card; while (vx1ub()) { int i = vx1ub.val(); IntSetRanges candCardR(iv[i]); unsigned int candidateCard = Iter::Ranges::size(candCardR); IntSetRanges candlb(iv[i]); LubRanges<SView> x0ub(x0); Iter::Ranges::Diff<IntSetRanges, LubRanges<SView> > diff(candlb, x0ub); bool selectSingleInconsistent = false; if (x1.cardMax() <= 1) { GlbRanges<SView> x0lb(x0); IntSetRanges candub(iv[i]); Iter::Ranges::Diff<GlbRanges<SView>, IntSetRanges > diff2(x0lb, candub); selectSingleInconsistent = diff2() || candidateCard < x0.cardMin(); } // exclude inconsistent x_i // an x_i is inconsistent if // * at most one x_i can be selected and there are // elements in x_0 that can't be in x_i // (selectSingleInconsistent) // * its min cardinality is greater than maxCard of x0 // * inter is not empty (there are elements in x_i // that can't be in x_0) if (selectSingleInconsistent || candidateCard > x0.cardMax() || diff()) { ModEvent me = (x1.exclude(home,i)); loopVar |= me_modified(me); GECODE_ME_CHECK(me); } else { stillSelected[i] = true; // if x_i is consistent, check whether we know // that its index is in x1 if (vx1() && vx1.val()==i) { // x0 >= candidate, candidate <= x0 // GlbRanges<SView> candlb(candidate); IntSetRanges candlb(iv[i]); ModEvent me = x0.includeI(home,candlb); loopVar |= me_modified(me); GECODE_ME_CHECK(me); ++vx1; } new (&before[i]) GLBndSet(home); before[i].update(home,sofarBefore); IntSetRanges cub(iv[i]); sofarBefore.includeI(home,cub); IntSetRanges clb(iv[i]); selectedInter.intersectI(home,clb); maxCard = std::max(maxCard, candidateCard); minCard = std::min(minCard, candidateCard); } ++vx1ub; } if (x1.cardMax()==0) { // Selector is empty, hence the result must be empty { GECODE_ME_CHECK(x0.cardMax(home,0)); } for (int i=n_iv; i--;) if (stillSelected[i]) before[i].dispose(home); selectedInter.dispose(home); sofarBefore.dispose(home); return home.ES_SUBSUMED(*this); } if (x1.cardMin() > 0) { // Selector is not empty, hence the intersection of the // possibly selected lower bounds is contained in x0 BndSetRanges si(selectedInter); ModEvent me = x0.includeI(home, si); loopVar |= me_modified(me); GECODE_ME_CHECK(me); me = x0.cardMin(home, minCard); loopVar |= me_modified(me); GECODE_ME_CHECK(me); } selectedInter.dispose(home); if (x1.cardMax() <= 1) { ModEvent me = x0.cardMax(home, maxCard); loopVar |= me_modified(me); GECODE_ME_CHECK(me); } { // x0 <= sofarBefore BndSetRanges sfB(sofarBefore); ModEvent me = x0.intersectI(home,sfB); loopVar |= me_modified(me); GECODE_ME_CHECK(me); } sofarBefore.dispose(home); GLBndSet sofarAfter(home); // In the second iteration, this time backwards, compute // sofarAfter as the union of all lub(x_j) with j>i for (int i=n_iv; i--;) { if (!stillSelected[i]) continue; BndSetRanges b(before[i]); BndSetRanges s(sofarAfter); GlbRanges<SView> x0lb(x0); Iter::Ranges::Union<BndSetRanges, BndSetRanges> inter(b,s); Iter::Ranges::Diff<GlbRanges<SView>, Iter::Ranges::Union<BndSetRanges,BndSetRanges> > diff(x0lb, inter); if (diff()) { ModEvent me = (x1.include(home,i)); loopVar |= me_modified(me); GECODE_ME_CHECK(me); // candidate != extra IntSetRanges ivi(iv[i]); if (!Iter::Ranges::subset(diff, ivi)) GECODE_ME_CHECK(ME_SET_FAILED); } IntSetRanges iviub(iv[i]); sofarAfter.includeI(home,iviub); before[i].dispose(home); } sofarAfter.dispose(home); } while (loopVar); if (x1.assigned()) { assert(x0.assigned()); return home.ES_SUBSUMED(*this); } return ES_FIX; }
void StlAdvancedFeaturesExample::primitive() { int i; if ( explicit_txn) dbstl::begin_txn(0, penv); db_vector<int, ElementHolder<int> > ivi(dbprim, penv); vector<int> spvi4; fill(ivi, spvi4); check_expr(is_equal(ivi, spvi4)); ivi.clear(false); db_vector<int, ElementHolder<int> > ivi2(dbprim, penv); vector<int> spvi5; fill(ivi2, spvi5); check_expr(is_equal(ivi2, spvi5)); size_t vsz = ivi2.size(); for (i = 0; i < (int)vsz - 1; i++) { ivi2[i] += 3; ivi2[i]--; ivi2[i] <<= 2; ivi2[i] = (~ivi2[i] | ivi2[i] & ivi2[i + 1] ^ (2 * (-ivi2[i + 1]) + ivi2[i]) * 3) / (ivi2[i] * ivi2[i + 1] + 1); spvi5[i] += 3; spvi5[i]--; spvi5[i] <<= 2; spvi5[i] = (~spvi5[i] | spvi5[i] & spvi5[i + 1] ^ (2 * (-spvi5[i + 1]) + spvi5[i]) * 3) / (spvi5[i] * spvi5[i + 1] + 1); } check_expr(is_equal(ivi2, spvi5)); ivi2.clear(false); typedef db_vector<double, ElementHolder<double> > dbl_vct_t; dbl_vct_t dvi(dbprim, penv); vector<double> dsvi; for (i = 0; i < 10; i++) { dvi.push_back(i * 3.14); dsvi.push_back(i * 3.14); } check_expr(is_equal(dvi, dsvi)); dbl_vct_t::iterator ditr; vector<double>::iterator sditr; for (ditr = dvi.begin(), sditr = dsvi.begin(); ditr != dvi.end(); ++ditr, ++sditr){ *ditr *= 2; *sditr *= 2; } check_expr(is_equal(dvi, dsvi)); for (i = 0; i < 9; i++) { dvi[i] /= (-dvi[i] / 3 + 2 * dvi[i + 1]) / (1 + dvi[i]) + 1; dsvi[i] /= (-dsvi[i] / 3 + 2 * dsvi[i + 1]) / (1 + dsvi[i]) + 1; } cout<<"\ndsvi after math operations: \n"; for (i = 0; i <= 9; i++) cout<<dsvi[i]<<" "; for (i = 0; i < 10; i++) { cout<<i<<"\t"; check_expr((int)(dvi[i] * 100000) == (int)(dsvi[i] * 100000)); } if ( explicit_txn) dbstl::commit_txn(penv); } // primitive