chocoteam / choco-solver

An open-source Java library for Constraint Programming
http://choco-solver.org/
BSD 4-Clause "Original" or "Old" License
690 stars 143 forks source link

[BUG] Bug in PropHybridTable -> ASupport #1102

Closed dimitri-justeau closed 2 months ago

dimitri-justeau commented 2 months ago

In choco-solver 4.10.16, I found a bug in the hybrid table constraint, apparently due to some situations leading to set a negative value in a BitSet. I tried running on different jvms (GraalVM 22 & OpenJDK 18), the behavior is the same.

Reproducible example:

import org.chocosolver.solver.Model;
import org.chocosolver.solver.constraints.extension.hybrid.HybridTuples;
import org.chocosolver.solver.constraints.extension.hybrid.ISupportable;
import org.chocosolver.solver.variables.IntVar;

import static org.chocosolver.solver.constraints.extension.hybrid.HybridTuples.*;
import static org.chocosolver.solver.constraints.extension.hybrid.HybridTuples.col;

public class Test {
    public static void main(String[] args) {
        Model m = new Model();
        IntVar[] intVars = m.intVarArray(3, 0, 5);
        ISupportable[][] htuples = new ISupportable[][]{
                {eq(1), gt(2), le(col(0))},
                {eq(2), le(2), ne(col(1))}

        };
        HybridTuples ht = new HybridTuples();
        ht.add(htuples);
        m.table(intVars, ht).post();
        for (int i = 0; i < 7; i++) {
            m.getSolver().solve();
        }
    }
}

Traceback:

Exception in thread "main" java.lang.IndexOutOfBoundsException: bitIndex < 0: -1
    at java.base/java.util.BitSet.set(BitSet.java:447)
    at org.chocosolver.solver.constraints.extension.hybrid.ASupport$AndSupport.support(ASupport.java:86)
    at org.chocosolver.solver.constraints.extension.hybrid.ISupportable$UnEqXC.support(ISupportable.java:167)
    at org.chocosolver.solver.constraints.extension.hybrid.ISupportable$Unary.support(ISupportable.java:65)
    at org.chocosolver.solver.constraints.extension.hybrid.ISupportable$Many.satisfiable(ISupportable.java:534)
    at org.chocosolver.solver.constraints.extension.hybrid.PropHybridTable.isTupleSupported(PropHybridTable.java:127)
    at org.chocosolver.solver.constraints.extension.hybrid.PropHybridTable.filter(PropHybridTable.java:164)
    at org.chocosolver.solver.constraints.extension.hybrid.PropHybridTable.propagate(PropHybridTable.java:88)
    at org.chocosolver.solver.propagation.PropagationEngine.propagateEvents(PropagationEngine.java:234)
    at org.chocosolver.solver.propagation.PropagationEngine.propagate(PropagationEngine.java:213)
    at org.chocosolver.solver.Solver.doPropagate(Solver.java:543)
    at org.chocosolver.solver.Solver.propagate(Solver.java:555)
    at org.chocosolver.solver.Solver.searchLoop(Solver.java:343)
    at org.chocosolver.solver.Solver.solve(Solver.java:311)
    at org.chocosolver.capi.Test.main(Test.java:24)