org.chocosolver.solver.constraints.extension.Tuples 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.extension;
import org.chocosolver.solver.exception.SolverException;
import org.chocosolver.solver.variables.IntVar;
import org.chocosolver.util.ESat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
/**
* A unique interface to declare tuples for table constraints.
* Handles both feasible tuples and forbidden tuples.
*
*
* @author Charles Prud'homme
* @since 22/04/2014
*/
public class Tuples {
//***********************************************************************************
// VARIABLES
//***********************************************************************************
private final boolean feasible;
protected final List tuples;
private int arity;
private int[] ranges;
private boolean allowStar;
private int star;
//***********************************************************************************
// CONSTRUCTOR
//***********************************************************************************
/**
* Create a list of tuples which represents all allowed tuples if feasible=true
* or a set of forbidden tuples if feasible=false.
* Lately, one can allow the presence of universal values, calling {@link #setUniversalValue(int)},
* meaning that some variables can take any values from their domain.
*
* @param values list of tuples
* @param feasible indicates whether the tuples are allowed or forbidden
*/
public Tuples(int[][] values, boolean feasible) {
this.feasible = feasible;
tuples = new ArrayList<>();
for(int[] t : values){
add(t);
}
}
/**
* Create a list of tuples which represents all allowed tuples if feasible=true
* or a set of forbidden tuples if feasible=false
*
* @param feasible indicates whether the tuples are allowed or forbidden
*/
public Tuples(boolean feasible) {
this.feasible = feasible;
tuples = new ArrayList<>();
}
/**
* Create a list of tuples which represents all allowed tuples, i.e. other tuples are forbidden
*/
public Tuples() {
this(true);
}
//***********************************************************************************
// METHODS
//***********************************************************************************
/**
* One can allow the presence of universal values,
* meaning that some variables can take any values from their domain.
* @param star the universal value that can appear in any tuple.
*/
public void setUniversalValue(int star){
this.star = star;
this.allowStar = true;
}
/**
* @return true if the presence of universal values is allowed.
*/
public boolean allowUniversalValue(){
return this.allowStar;
}
/**
* @return the value of the symbol which denotes that
* some variables can take any values from their domain.
*/
public int getStarValue(){
assert allowUniversalValue();
return this.star;
}
/**
* Checks entailment of a table constraint over vars with this Tuples object
* @param vars set of integer variables to test
* @return an ESat object indicating the entailement of the table over vars and this
*/
public ESat check(IntVar... vars) {
if(nbTuples() == 0){
return isFeasible()? ESat.FALSE: ESat.TRUE;
}
if(vars.length != arity){
throw new SolverException("The given variable array does not match the arity: " + arity);
}
int[] values = new int[vars.length];
for (int i=0;i {
@Override
public int compare(int[] o1, int[] o2) {
int i = 0;
int l = o1.length;
while (i < l && o1[i] == o2[i]) {
i++;
}
return (i == l ? 0 : o1[i] - o2[i]);
}
}
}