experiments on table constraint

This commit is contained in:
Laurent Perron
2016-07-15 11:20:33 -07:00
parent 4ac70c7a27
commit ea201416a1
3 changed files with 45 additions and 11 deletions

View File

@@ -2464,6 +2464,11 @@ class UnsortedNullableRevBitset {
// the active bitset was changed in the process.
bool RevSubtract(Solver* const solver, const std::vector<uint64>& mask);
// This method ands the mask with the active bitset. It returns true if
// the active bitset was changed in the process.
bool RevAnd(Solver* const solver, const std::vector<uint64>& mask);
// This method returns the number of non null 64 bit words in the bitset
// representation.
int ActiveWordSize() const { return active_words_.Size(); }

View File

@@ -566,6 +566,7 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint {
case 1: {
SetTempMask(var_index, var->Min() - omin);
changed = AndTempMaskWithActive();
// changed = AndMaskWithActive(var_index, var->Min() - omin);
break;
}
case 2: {
@@ -720,10 +721,17 @@ class CompactPositiveTableConstraint : public BasePositiveTableConstraint {
// ----- Helpers during propagation -----
bool AndTempMaskWithActive() {
for (int i : active_tuples_.active_words()) {
temp_mask_[i] = ~temp_mask_[i];
const bool result = active_tuples_.RevAnd(solver(), temp_mask_);
if (active_tuples_.Empty()) {
solver()->Fail();
}
const bool result = active_tuples_.RevSubtract(solver(), temp_mask_);
return result;
}
bool AndMaskWithActive(int var_index, int64 value_index) {
CHECK_EQ(masks_[var_index][value_index].size(), word_length_);
const bool result =
active_tuples_.RevAnd(solver(), masks_[var_index][value_index]);
if (active_tuples_.Empty()) {
solver()->Fail();
}

View File

@@ -239,18 +239,40 @@ void UnsortedNullableRevBitset::Init(Solver* const solver,
bool UnsortedNullableRevBitset::RevSubtract(Solver* const solver,
const std::vector<uint64>& mask) {
bool changed = false;
for (int i = 0; i < active_words_.Size(); ++i) {
const int index = active_words_.Element(i);
for (int index : active_words_) {
if (bits_[index] & mask[index]) {
changed = true;
bits_.SetValue(solver, index, bits_[index] & ~mask[index]);
}
}
// Update active_words_ in reverse order.
for (int i = active_words_.Size() - 1; i >= 0; --i) {
const int index = active_words_.Element(i);
if (!bits_[index]) {
active_words_.Remove(solver, index);
if (changed) {
for (int i = active_words_.Size() - 1; i >= 0; --i) {
const int index = active_words_.Element(i);
if (!bits_[index]) {
active_words_.Remove(solver, index);
}
}
}
return changed;
}
bool UnsortedNullableRevBitset::RevAnd(Solver* const solver,
const std::vector<uint64>& mask) {
bool changed = false;
for (int index : active_words_) {
if (bits_[index] & ~mask[index]) {
changed = true;
bits_.SetValue(solver, index, bits_[index] & mask[index]);
}
}
// Update active_words_ in reverse order.
if (changed) {
for (int i = active_words_.Size() - 1; i >= 0; --i) {
const int index = active_words_.Element(i);
if (!bits_[index]) {
active_words_.Remove(solver, index);
}
}
}
return changed;
@@ -263,8 +285,7 @@ bool UnsortedNullableRevBitset::Intersects(const std::vector<uint64>& mask,
if (mask[*support_index] & bits_[*support_index]) {
return true;
}
for (int i = 0; i < active_words_.Size(); ++i) {
const int index = active_words_.Element(i);
for (int index : active_words_) {
if (bits_[index] & mask[index]) {
*support_index = index;
return true;