org.chocosolver.solver.constraints.ternary.PropMaxBC Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of choco-solver Show documentation
Show all versions of choco-solver Show documentation
Open-source constraint solver.
/*
* This file is part of choco-solver, http://choco-solver.org/
*
* Copyright (c) 2023, IMT Atlantique. All rights reserved.
*
* Licensed under the BSD 4-clause license.
*
* See LICENSE file in the project root for full license information.
*/
package org.chocosolver.solver.constraints.ternary;
import org.chocosolver.solver.constraints.Propagator;
import org.chocosolver.solver.constraints.PropagatorPriority;
import org.chocosolver.solver.exception.ContradictionException;
import org.chocosolver.solver.variables.IntVar;
import org.chocosolver.solver.variables.events.IntEventType;
import org.chocosolver.util.ESat;
/**
* X = MAX(Y,Z)
*
* ensures bound consistency
*
* @author Charles Prud'homme
* @since 19/04/11
*/
public class PropMaxBC extends Propagator {
private final IntVar BST;
private final IntVar v1;
private final IntVar v2;
public PropMaxBC(IntVar X, IntVar Y, IntVar Z) {
super(new IntVar[]{X, Y, Z}, PropagatorPriority.TERNARY, false);
this.BST = vars[0];
this.v1 = vars[1];
this.v2 = vars[2];
}
@Override
public int getPropagationConditions(int vIdx) {
return IntEventType.boundAndInst();
}
@Override
public void propagate(int evtmask) throws ContradictionException {
boolean change;
do {
change = vars[0].updateLowerBound(Math.max(vars[1].getLB(), vars[2].getLB()), this);
change |= vars[0].updateUpperBound(Math.max(vars[1].getUB(), vars[2].getUB()), this);
change |= vars[1].updateUpperBound(vars[0].getUB(), this);
change |= vars[2].updateUpperBound(vars[0].getUB(), this);
if (vars[2].getUB() < vars[0].getLB()) {
change |= vars[1].updateLowerBound(vars[0].getLB(), this);
}
if (vars[1].getUB() < vars[0].getLB()) {
change |= vars[2].updateLowerBound(vars[0].getLB(), this);
}
} while (change);
if(vars[0].isInstantiated()){
int bst = vars[0].getValue();
if(vars[1].isInstantiatedTo(bst) || vars[2].isInstantiatedTo(bst)){
setPassive();
}
}
}
@Override
public ESat isEntailed() {
int ub = vars[0].getUB();
if (vars[1].getLB() > ub || vars[2].getLB() > ub) {
return ESat.FALSE;
}
if (Math.max(vars[1].getUB(), vars[2].getUB()) < vars[0].getLB()) {
return ESat.FALSE;
}
if (vars[1].getUB() > ub || vars[2].getUB() > ub) {
return ESat.UNDEFINED;
}
if (vars[0].isInstantiated()
&& (vars[1].isInstantiatedTo(ub) || vars[2].isInstantiatedTo(ub))) {
return ESat.TRUE;
}
return ESat.UNDEFINED;
}
@Override
public String toString() {
return BST.toString() + ".MAX(" + v1.toString() + "," + v2.toString() + ")";
}
}