Skip to content

Commit

Permalink
Fix PropCount_AC wrt bounded domains (#1076)
Browse files Browse the repository at this point in the history
* fix PropCount_AC wrt bounded domains

* fix propagation condition in PropCount_AC
  • Loading branch information
ArthurGodet committed Jan 9, 2024
1 parent b4bf328 commit cf75588
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public String toString() {
st.append("..., ");
}
st.append("limit=").append(vars[vars.length - 1].getName());
st.append(", value=").append(value).append(')');
st.append(", value=").append(value).append(')');
return st.toString();
}

Expand Down Expand Up @@ -112,15 +112,17 @@ public void propagate(int varIdx, int mask) throws ContradictionException {
if (possibles.contains(varIdx)) {
if (!vars[varIdx].contains(value)) {
possibles.remove(varIdx);
filter();
forcePropagate(PropagatorEventType.CUSTOM_PROPAGATION);
} else if (vars[varIdx].isInstantiated()) {
possibles.remove(varIdx);
mandatories.add(varIdx);
filter();
forcePropagate(PropagatorEventType.CUSTOM_PROPAGATION);
} else if (!vars[varIdx].hasEnumeratedDomain() && (vars[varIdx].getLB() == value || vars[varIdx].getUB() == value)) {
forcePropagate(PropagatorEventType.CUSTOM_PROPAGATION);
}
}
} else {
filter();
forcePropagate(PropagatorEventType.CUSTOM_PROPAGATION);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@
*/
package org.chocosolver.solver.constraints.nary;

import org.chocosolver.solver.Cause;
import org.chocosolver.solver.Settings;
import org.chocosolver.solver.Model;
import org.chocosolver.solver.Solver;
import org.chocosolver.solver.constraints.Constraint;
import org.chocosolver.solver.constraints.extension.Tuples;
import org.chocosolver.solver.exception.ContradictionException;
import org.chocosolver.solver.variables.BoolVar;
import org.chocosolver.solver.variables.IntVar;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.util.LinkedList;
Expand All @@ -30,6 +33,7 @@
import static org.chocosolver.solver.search.strategy.Search.randomSearch;
import static org.chocosolver.util.tools.ArrayUtils.append;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;

/**
* <br/>
Expand Down Expand Up @@ -249,4 +253,103 @@ public Constraint getDecomposition(Model model, IntVar[] vs, IntVar occ, int val
return model.sum(bs, "=", occ);
}

@DataProvider(name = "testFilteringToZeroProvider")
public static Object[][] testFilteringToZeroProvider() {
return new Object[][] {{true}, {false}};
}

@Test(groups="1s", timeOut=60000, dataProvider = "testFilteringToZeroProvider")
public void testFilteringToZero(Boolean boundedDomain) {
Model model = new Model();
IntVar[] vars = model.intVarArray("vars", 10, 0, 10, boundedDomain);
IntVar count = model.intVar("count", 0, 10);
model.count(4, vars, count).post();

try {
model.getSolver().propagate();
for (int i = 0; i < vars.length; i++) {
Assert.assertEquals(11, vars[i].getDomainSize());
}
Assert.assertEquals(11, count.getDomainSize());
} catch (ContradictionException ex) {
fail();
}

try {
for (int i = 1; i < vars.length; i++) {
vars[i].updateLowerBound(5, Cause.Null);
}
model.getSolver().propagate();
for (int i = 0; i < vars.length; i++) {
if (i == 0) {
Assert.assertEquals(11, vars[i].getDomainSize());
} else {
Assert.assertEquals(6, vars[i].getDomainSize());
}
}
Assert.assertEquals(0, count.getLB());
Assert.assertEquals(1, count.getUB());
} catch (ContradictionException ex) {
fail();
}

try {
count.updateUpperBound(0, Cause.Null);
model.getSolver().propagate();
for (int i = 0; i < vars.length; i++) {
if (i == 0) {
if (vars[i].hasEnumeratedDomain()) {
Assert.assertEquals(10, vars[i].getDomainSize());
Assert.assertFalse(vars[i].contains(4));
} else {
Assert.assertEquals(11, vars[i].getDomainSize());
Assert.assertTrue(vars[i].contains(4));
}
} else {
Assert.assertEquals(6, vars[i].getDomainSize());
Assert.assertFalse(vars[i].contains(4));
}
}
Assert.assertTrue(count.isInstantiatedTo(0));
} catch (ContradictionException ex) {
fail();
}

try {
// To test (in debug mode), that we do not enter in PropCount_AC.filter()
for (int j = 1; j < 4; j++) {
vars[0].updateLowerBound(j, Cause.Null);
model.getSolver().propagate();
for (int i = 0; i < vars.length; i++) {
if (i == 0) {
if (vars[i].hasEnumeratedDomain()) {
Assert.assertEquals(10 - j, vars[i].getDomainSize());
Assert.assertFalse(vars[i].contains(4));
} else {
Assert.assertEquals(11 - j, vars[i].getDomainSize());
Assert.assertTrue(vars[i].contains(4));
}
} else {
Assert.assertEquals(6, vars[i].getDomainSize());
Assert.assertFalse(vars[i].contains(4));
}
}
Assert.assertTrue(count.isInstantiatedTo(0));
}
} catch (ContradictionException ex) {
fail();
}

try {
vars[0].updateLowerBound(4, Cause.Null);
model.getSolver().propagate();
for (int i = 0; i < vars.length; i++) {
Assert.assertEquals(6, vars[i].getDomainSize());
Assert.assertFalse(vars[i].contains(4));
}
Assert.assertTrue(count.isInstantiatedTo(0));
} catch (ContradictionException ex) {
fail();
}
}
}

0 comments on commit cf75588

Please sign in to comment.