All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.chocosolver.solver.constraints.IReificationFactory Maven / Gradle / Ivy

There is a newer version: 4.10.17
Show newest version
/*
 * 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;

import org.chocosolver.solver.ISelf;
import org.chocosolver.solver.Model;
import org.chocosolver.solver.constraints.reification.*;
import org.chocosolver.solver.search.SearchState;
import org.chocosolver.solver.variables.BoolVar;
import org.chocosolver.solver.variables.IntVar;
import org.chocosolver.util.ESat;
import org.chocosolver.util.objects.setDataStructures.iterable.IntIterableRangeSet;

/**
 * Interface to reify constraints
 * A kind of factory relying on interface default implementation to allow (multiple) inheritance
 *
 * @author Jean-Guillaume FAGES
 * @since 4.0.0
 */
public interface IReificationFactory extends ISelf {

    //***********************************************************************************
    // Non-reifiable reification constraints
    //***********************************************************************************

    /**
     * Posts a constraint ensuring that if ifCstr is satisfied, then thenCstr must be satisfied as well
     * Otherwise, elseCstr must be satisfied
     * ifCstr => ThenCstr
     * not(ifCstr) => ElseCstr
     * 

* BEWARE : it is automatically posted (it cannot be reified) * * @param ifCstr a constraint * @param thenCstr a constraint * @param elseCstr a constraint */ default void ifThenElse(Constraint ifCstr, Constraint thenCstr, Constraint elseCstr) { ifThenElse(ifCstr.reify(), thenCstr, elseCstr); } /** * Posts an implication constraint: ifVar => thenCstr && not(ifVar) => elseCstr. *
* Ensures: *

- ifVar = 1 => thenCstr is satisfied,
*

- ifVar = 0 => elseCstr is satisfied,
*

- thenCstr is not satisfied => ifVar = 0
*

- elseCstr is not satisfied => ifVar = 1
*

*

In order to get ifVar <=> thenCstr, use reification *

* BEWARE : it is automatically posted (it cannot be reified) * * @param ifVar variable of reification * @param thenCstr the constraint to be satisfied when ifVar = 1 * @param elseCstr the constraint to be satisfied when ifVar = 0 */ default void ifThenElse(BoolVar ifVar, Constraint thenCstr, Constraint elseCstr) { ifThen(ifVar, thenCstr); ifThen(ifVar.not(), elseCstr); } /** * Posts a constraint ensuring that if ifCstr is satisfied, then thenCstr is satisfied as well *

* BEWARE : it is automatically posted (it cannot be reified) * * @param ifCstr a constraint * @param thenCstr a constraint */ default void ifThen(Constraint ifCstr, Constraint thenCstr) { ifThen(ifCstr.reify(), thenCstr); } /** * Posts an implication constraint: ifVar => thenCstr * Also called half reification constraint * Ensures:
*

- ifVar = 1 => thenCstr is satisfied,
*

- thenCstr is not satisfied => ifVar = 0
*

* Example :
* - ifThen(b1, arithm(v1, "=", 2));: * b1 is equal to 1 => v1 = 2, so v1 != 2 => b1 is equal to 0 * But if b1 is equal to 0, nothing happens *

* BEWARE : it is automatically posted (it cannot be reified) *

* * @param ifVar variable of reification * @param thenCstr the constraint to be satisfied when ifVar = 1 */ default void ifThen(BoolVar ifVar, Constraint thenCstr) { // PRESOLVE if (ifVar.contains(1)) { if (ifVar.isInstantiated()) { thenCstr.post(); } else if (thenCstr.isSatisfied() == ESat.FALSE) { thenCstr.ignore(); ref().arithm(ifVar, "=", 0).post(); } // END OF PRESOLVE else { ref().arithm(ifVar, "<=", thenCstr.reify()).post(); } }else{ thenCstr.ignore(); } } /** * Posts an equivalence constraint stating that * cstr1 is satisfied <=> cstr2 is satisfied, *

* BEWARE : it is automatically posted (it cannot be reified) * * @param cstr1 a constraint to be satisfied if and only if cstr2 is satisfied * @param cstr2 a constraint to be satisfied if and only if cstr1 is satisfied */ default void ifOnlyIf(Constraint cstr1, Constraint cstr2) { reification(cstr1.reify(), cstr2); } /** * Reify a constraint with a boolean variable: * var = 1 <=> cstr is satisfied, *

* Equivalent to ifOnlyIf *

* BEWARE : it is automatically posted (it cannot be reified) * * @param var variable of reification * @param cstr the constraint to be satisfied if and only if var = 1 */ default void reification(BoolVar var, Constraint cstr) { // PRESOLVE ESat entail = cstr.isSatisfied(); if (var.isInstantiatedTo(1)) { cstr.post(); } else if (var.isInstantiatedTo(0)) { cstr.getOpposite().post(); } else if (entail == ESat.TRUE) { cstr.ignore(); ref().arithm(var, "=", 1).post(); } else if (entail == ESat.FALSE) { cstr.ignore(); ref().arithm(var, "=", 0).post(); } // END OF PRESOLVE else { cstr.reifyWith(var); } } /** * Posts one constraint that expresses : (x = c) ⇔ b. * Bypasses the reification system. * * @param X a integer variable * @param C an int * @param B a boolean variable */ default void reifyXeqC(IntVar X, int C, BoolVar B) { // no check to allow addition during resolution if (ref().getSolver().getSearchState() == SearchState.NEW) { if (X.isInstantiatedTo(C)) { ref().arithm(B, "=", 1).post(); return; } else if (!X.contains(C)) { ref().arithm(B, "=", 0).post(); return; } } ref().post(new Constraint(ConstraintsName.BASIC_REI, new PropXeqCReif(X, C, B))); } /** * Posts one constraint that expresses : (x ≠ c) ⇔ b. * Bypasses the reification system. * * @param X a integer variable * @param C an int * @param B a boolean variable */ default void reifyXneC(IntVar X, int C, BoolVar B) { // no check to allow addition during resolution reifyXeqC(X, C, B.not()); } /** * Posts one constraint that expresses : (x = y) ⇔ b. * Bypasses the reification system. * * @param X an integer variable * @param Y an integer variable * @param B a boolean variable */ @SuppressWarnings("SuspiciousNameCombination") default void reifyXeqY(IntVar X, IntVar Y, BoolVar B) { if (X.isAConstant()) { reifyXeqC(Y, X.getValue(), B); } else if (Y.isAConstant()) { reifyXeqC(X, Y.getValue(), B); } else { // no check to allow addition during resolution ref().post(new Constraint(ConstraintsName.BASIC_REI, new PropXeqYCReif(X, Y, 0, B))); } } /** * Posts one constraint that expresses : (x ≠ y) ⇔ b. * Bypasses the reification system. * * @param X an integer variable * @param Y an integer variable * @param B a boolean variable */ @SuppressWarnings("SuspiciousNameCombination") default void reifyXneY(IntVar X, IntVar Y, BoolVar B) { if (X.isAConstant()) { reifyXneC(Y, X.getValue(), B); } else if (Y.isAConstant()) { reifyXneC(X, Y.getValue(), B); } else { // no check to allow addition during resolution reifyXeqY(X, Y, B.not()); } } /** * Posts one constraint that expresses : (x = y + c) ⇔ b. * Bypasses the reification system. * * @param X an integer variable * @param Y an integer variable * @param C an int * @param B a boolean variable */ @SuppressWarnings("SuspiciousNameCombination") default void reifyXeqYC(IntVar X, IntVar Y, int C, BoolVar B) { if (X.isAConstant()) { reifyXeqC(Y, X.getValue() - C, B); } else if (Y.isAConstant()) { reifyXeqC(X, Y.getValue() + C, B); } else { // no check to allow addition during resolution ref().post(new Constraint(ConstraintsName.BASIC_REI, new PropXeqYCReif(X, Y, C, B))); } } /** * Posts one constraint that expresses : (x ≠ y + c) ⇔ b. * Bypasses the reification system. * * @param X an integer variable * @param Y an integer variable * @param C an int * @param B a boolean variable */ @SuppressWarnings("SuspiciousNameCombination") default void reifyXneYC(IntVar X, IntVar Y, int C, BoolVar B) { if (X.isAConstant()) { reifyXneC(Y, X.getValue() - C, B); } else if (Y.isAConstant()) { reifyXneC(X, Y.getValue() + C, B); } else { // no check to allow addition during resolution reifyXeqYC(X, Y, C, B.not()); } } /** * Posts one constraint that expresses : (x < c) ⇔ b. * Bypasses the reification system. * * @param X a integer variable * @param C an int * @param B a boolean variable */ default void reifyXltC(IntVar X, int C, BoolVar B) { // no check to allow addition during resolution if (ref().getSolver().getSearchState() == SearchState.NEW) { if (X.getUB() < C) { ref().arithm(B, "=", 1).post(); return; } else if (X.getLB() >= C) { ref().arithm(B, "=", 0).post(); return; } } ref().post(new Constraint(ConstraintsName.BASIC_REI, new PropXltCReif(X, C, B))); } /** * Posts one constraint that expresses : (x > c) ⇔ b. * Bypasses the reification system. * * @param X a integer variable * @param C an int * @param B a boolean variable */ default void reifyXgtC(IntVar X, int C, BoolVar B) { // no check to allow addition during resolution reifyXltC(X, C + 1, B.not()); } /** * Posts one constraint that expresses : (x < y) ⇔ b. * Bypasses the reification system. * * @param X an integer variable * @param Y an integer variable * @param B a boolean variable */ @SuppressWarnings("SuspiciousNameCombination") default void reifyXltY(IntVar X, IntVar Y, BoolVar B) { if (X.isAConstant()) { reifyXgtC(Y, X.getValue(), B); } else if (Y.isAConstant()) { reifyXltC(X, Y.getValue(), B); } else { // no check to allow addition during resolution reifyXltYC(X, Y, 0, B); } } /** * Posts one constraint that expresses : (x > y) ⇔ b. * Bypasses the reification system. * * @param X an integer variable * @param Y an integer variable * @param B a boolean variable */ default void reifyXgtY(IntVar X, IntVar Y, BoolVar B) { reifyXltYC(X, Y, 1, B.not()); } /** * Posts one constraint that expresses : (x ≤ y) ⇔ b. * Bypasses the reification system. * * @param X an integer variable * @param Y an integer variable * @param B a boolean variable */ default void reifyXleY(IntVar X, IntVar Y, BoolVar B) { // no check to allow addition during resolution reifyXltYC(X, Y, 1, B); } /** * Posts one constraint that expresses : (x ≥ y) ⇔ b. * Bypasses the reification system. * * @param X an integer variable * @param Y an integer variable * @param B a boolean variable */ default void reifyXgeY(IntVar X, IntVar Y, BoolVar B) { // no check to allow addition during resolution reifyXltYC(X, Y, 0, B.not()); } /** * Posts one constraint that expresses : (x < y + c) ⇔ b. * Bypasses the reification system. * * @param X an integer variable * @param Y an integer variable * @param C an int * @param B a boolean variable */ @SuppressWarnings("SuspiciousNameCombination") default void reifyXltYC(IntVar X, IntVar Y, int C, BoolVar B) { // no check to allow addition during resolution if (X.isAConstant()) { reifyXgtC(Y, X.getValue() - C, B); } else if (Y.isAConstant()) { reifyXltC(X, Y.getValue() + C, B); } else { ref().post(new Constraint(ConstraintsName.BASIC_REI, new PropXltYCReif(X, Y, C, B))); } } /** * Posts one constraint that expresses : (x > y + c) ⇔ b. * Bypasses the reification system. * * @param X an integer variable * @param Y an integer variable * @param C an int * @param B a boolean variable */ default void reifyXgtYC(IntVar X, IntVar Y, int C, BoolVar B) { // no check to allow addition during resolution reifyXltYC(X, Y, C + 1, B.not()); } /** * Posts one constraint that expresses : (X ∈ S) ⇔ B. * Bypasses the reification system. * * @param X an integer variable * @param S a set of values * @param B a boolean variable */ default void reifyXinS(IntVar X, IntIterableRangeSet S, BoolVar B) { // no check to allow addition during resolution ref().post(new Constraint(ConstraintsName.BASIC_REI, new PropXinSReif(X, S, B))); } /** * Posts one constraint that expresses : (X ∉ S) ⇔ B. * Bypasses the reification system. * * @param X an integer variable * @param S a set of values * @param B a boolean variable */ default void reifyXnotinS(IntVar X, IntIterableRangeSet S, BoolVar B) { // no check to allow addition during resolution ref().post(new Constraint(ConstraintsName.BASIC_REI, new PropXinSReif(X, S, B.not()))); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy