BitSet BitSet::operator<<(const int shift) { BitSet result; for (int i = 0; i < shift; ++i) { result.add(false); } for (int i = 0; i < this->length(); ++i) { result.add((*this)[i]); } return result; }
BitSet BitSet::operator&(const BitSet& that) { BitSet bs; int maxLength = std::max(this->length(), that.length()); for (int i = 0; i < maxLength; ++i) { if (i >= this->length() || i >= that.length()) { bs.add(false); } else { bs.add((*this)[i] && that[i]); } } return bs; }
/* * Restricted propagation procedure. Used when a direction is solved, but no new q-intersection is found. * Same as propagate, except that upper bounds are not recorded (because we did not find a curr_qinter to work with). */ void propagate_no_ub(const Array<IntervalVector>& boxes, IntStack ***dirboxes, int dimension, bool left, IntervalVector& hull_qinter, vector<BitSet *>& nogoods) { unsigned int n = hull_qinter.size(); unsigned int p = boxes.size(); IntervalVector b(n); /* Create the new nogood */ BitSet *newNogood = new BitSet(0,p-1,BitSet::empt); /* We iterate through the boxes to propagate bounds */ /* This does not seem to be optimal ; maybe we should study directly the directions' lists ? */ for (int i=0; i<p; i++) { b = boxes[i]; /* Check if the box can be added to the new nogood */ if ((left && (b[dimension].lb() < hull_qinter[dimension].lb())) || (!left && (b[dimension].ub() > hull_qinter[dimension].ub()))) { newNogood->add(i); } /* Check if the box is strictly outside our current q-inter hull */ if ((left && (b[dimension].ub() < hull_qinter[dimension].lb())) || (!left && (b[dimension].lb() > hull_qinter[dimension].ub()))) { for (int k=dimension+1; k<n; k++) { if (dirboxes[k][0]->contain(i)) dirboxes[k][0]->remove(i); if (dirboxes[k][1]->contain(i)) dirboxes[k][1]->remove(i); } continue; } } nogoods.push_back(newNogood); }
BitSet BitSet::operator!() { BitSet bs; for (int i = 0; i < this->bitLength; ++i) { bool bit = (*this)[i]; bs.add(!bit); } return bs; }
/* * Bound propagation and nogood recording. Assumes that dimensions are processed in the ascending order and left side first. */ void propagate(const Array<IntervalVector>& boxes, IntStack ***dirboxes, int dimension, bool left, IntervalVector& curr_qinter, vector<BitSet *>& nogoods) { unsigned int n = curr_qinter.size(); unsigned int p = boxes.size(); IntervalVector b(n); /* Create the new nogood */ BitSet *newNogood = new BitSet(0,p-1,BitSet::empt); /* We iterate through the boxes to propagate bounds */ /* This does not seem to be optimal ; maybe we should study directly the directions' lists ? */ for (int i=0; i<p; i++) { b = boxes[i]; /* Check if the box can be added to the new nogood */ if ((left && (b[dimension].lb() < curr_qinter[dimension].lb())) || (!left && (b[dimension].ub() > curr_qinter[dimension].ub()))) { newNogood->add(i); } /* First check : the q-inter is a valid upper bound for the opposite direction */ if (left && (b[dimension].ub() <= curr_qinter[dimension].ub())) { if (dirboxes[dimension][1]->contain(i)) dirboxes[dimension][1]->remove(i); } /* Second check : check if the box is strictly outside our current q-inter hull */ if ((left && (b[dimension].ub() < curr_qinter[dimension].lb())) || (!left && (b[dimension].lb() > curr_qinter[dimension].ub()))) { for (int k=dimension+1; k<n; k++) { if (dirboxes[k][0]->contain(i)) dirboxes[k][0]->remove(i); if (dirboxes[k][1]->contain(i)) dirboxes[k][1]->remove(i); } continue; } /* Third check : the q-intersection provides a valid upper bound for the orthogonal dimensions. */ for (int j=dimension+1; j<n; j++) { if (b[j].lb() >= curr_qinter[j].lb()) { if (dirboxes[j][0]->contain(i)) dirboxes[j][0]->remove(i); } if (b[j].ub() <= curr_qinter[j].ub()) { if (dirboxes[j][1]->contain(i)) dirboxes[j][1]->remove(i); } } } nogoods.push_back(newNogood); }
BitSet *gen(BasicBlock *bb) { BitSet *result = new BitSet(size); result->add(bb->number()); return result; }