Skip to content

[BUG] Fine events may lead to unexpected behavior when used with incremental propagators on initial propagation #1122

@cprudhom

Description

@cprudhom

This small artificial example shows the problem.
An event can be received (and handled) twice: once during initial propagation, the other one during the normal propagation that follows.

private class MyProp extends Propagator{

        BitSet fixed;
        public MyProp(Variable[] vars) {
            super(vars, PropagatorPriority.LINEAR, true);
            fixed = new BitSet(vars.length);
            fixed.clear();
        }

        @Override
        public void propagate(int evtmask) throws ContradictionException {
            for(int i = 0; i < vars.length; i++){
                if(vars[i].isInstantiated()){
                    fixed.set(i);
                }
            }
        }

        @Override
        public void propagate(int idxVarInProp, int mask) throws ContradictionException {
            if(fixed.get(idxVarInProp)){
                throw new UnsupportedOperationException("Should not be called!");
            }
        }

        @Override
        public ESat isEntailed() {
            return TRUE;
        }
    }

    @Test(groups = "1s")
    public void testFineEvents() throws ContradictionException {
        Model m = new Model();
        IntVar[] X = m.intVarArray(2, 0,2);
        X[0].instantiateTo(1, Cause.Null);
        new Constraint("TEST", new MyProp(X)).post();
        m.getSolver().solve();
    }

Fix:

In PropagationEngine.java, update initialize():

    public void initialize() throws SolverException {
        if (!init) {
            notEmpty = 0;
            init = true;
            while (!var_queue.isEmpty()) {
                var_queue.pollFirst().clearEvents();
            }
//...

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions