
org.xcsp.modeler.api.ProblemAPI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xcsp3-tools Show documentation
Show all versions of xcsp3-tools Show documentation
Java Tools for parsing XCSP3 instances, compiling JvCSP3 models, and checking solutions. For more information about XCSP3, follow www.xcsp.org
The newest version!
package org.xcsp.modeler.api;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.xcsp.common.Condition;
import org.xcsp.common.FunctionalInterfaces.IntToDom;
import org.xcsp.common.FunctionalInterfaces.Intx1Predicate;
import org.xcsp.common.FunctionalInterfaces.Intx2Predicate;
import org.xcsp.common.FunctionalInterfaces.Intx2ToDom;
import org.xcsp.common.FunctionalInterfaces.Intx3Predicate;
import org.xcsp.common.FunctionalInterfaces.Intx3ToDom;
import org.xcsp.common.FunctionalInterfaces.Intx4ToDom;
import org.xcsp.common.FunctionalInterfaces.Intx5ToDom;
import org.xcsp.common.IVar;
import org.xcsp.common.IVar.Var;
import org.xcsp.common.Range;
import org.xcsp.common.Size.Size1D;
import org.xcsp.common.Size.Size2D;
import org.xcsp.common.Size.Size3D;
import org.xcsp.common.Size.Size4D;
import org.xcsp.common.Size.Size5D;
import org.xcsp.common.Types.TypeClass;
import org.xcsp.common.Types.TypeConditionOperatorRel;
import org.xcsp.common.Types.TypeConditionOperatorSet;
import org.xcsp.common.Types.TypeObjective;
import org.xcsp.common.Types.TypeOperatorRel;
import org.xcsp.common.domains.Domains.Dom;
import org.xcsp.common.predicates.XNode;
import org.xcsp.common.predicates.XNodeParent;
import org.xcsp.common.structures.Automaton;
import org.xcsp.common.structures.Table;
import org.xcsp.common.structures.Transition;
import org.xcsp.common.structures.Transitions;
import org.xcsp.modeler.api.ProblemAPIBase.Occurrences.OccurrencesInt;
import org.xcsp.modeler.api.ProblemAPIBase.Occurrences.OccurrencesInt1D;
import org.xcsp.modeler.api.ProblemAPIBase.Occurrences.OccurrencesIntRange;
import org.xcsp.modeler.api.ProblemAPIBase.Occurrences.OccurrencesIntRange1D;
import org.xcsp.modeler.api.ProblemAPIBase.Occurrences.OccurrencesVar1D;
import org.xcsp.modeler.entities.CtrEntities.CtrAlone;
import org.xcsp.modeler.entities.CtrEntities.CtrEntity;
import org.xcsp.modeler.entities.ObjEntities.ObjEntity;
public interface ProblemAPI extends ProblemAPIOnVars, ProblemAPIOnVals, ProblemAPISymbolic {
// ************************************************************************
// ***** Methods for defining domains, sizes and ranges
// ************************************************************************
/**
* Returns an integer domain composed of the sorted distinct values that come from the specified array and that
* respect the specified predicate.
*
* @param values
* a 1-dimensional array of integers
* @param p
* a predicate allowing us to test if a value {@code v} must be kept in the domain
* @return an integer domain composed of the sorted distinct values that come from the specified array and that
* respect the specified predicate
*/
default Dom dom(int[] values, Intx1Predicate p) {
control(values.length > 0, "At least one value must be specified");
values = IntStream.of(values).sorted().distinct().filter(v -> p == null || p.test(v)).toArray();
return new Dom(values);
}
/**
* Returns an integer domain composed of the sorted distinct values that come from the specified array.
*
* @param values
* a 1-dimensional array of integers
* @return an integer domain composed of the sorted distinct values that come from the specified array
*/
default Dom dom(int[] values) {
if (values == null || values.length == 0) {
System.out.println("Empty domain when calling dom(). Is that correct?");
return null;
}
return dom(values, null);
}
/**
* Returns an integer domain composed of the sorted distinct values that come from the specified values.
*
* @param value
* a first integer (value)
* @param otherValues
* a sequence of other integers (values)
* @return an integer domain composed of the sorted distinct values that come from the specified values
*/
default Dom dom(int value, int... otherValues) {
return dom(IntStream.range(0, otherValues.length + 1).map(i -> i == 0 ? value : otherValues[i - 1]).toArray());
}
/**
* Returns an integer domain composed of the sorted distinct values that come from the specified collection.
*
* @param values
* a collection of integers (values)
* @return an integer domain composed of the sorted distinct values that come from the specified collection
*/
default Dom dom(Collection values) {
return dom(values.stream().mapToInt(i -> i).toArray());
}
/**
* Returns an integer domain composed of the sorted distinct values that come from the specified stream
*
* @param values
* a stream of integer values
* @return an integer domain composed of the sorted distinct values that come from the specified stream
*/
default Dom dom(IntStream values) {
return dom(values.toArray());
}
/**
* Returns an integer domain composed of the sorted distinct values that come from the specified array.
*
* @param m
* a 2-dimensional array of variables
* @return an integer domain composed of the sorted distinct values that come from the specified array
*/
default Dom dom(int[][] m) {
return dom(Stream.of(m).map(t -> Arrays.stream(t)).flatMapToInt(i -> i).toArray());
}
/**
* Returns an integer domain composed of the values contained in the specified range.
*
* @param range
* the range of values to be considered for the domain
* @return an integer domain composed of the values contained in the specified range
*/
default Dom dom(Range range) {
assert range.length() > 0;
return range.length() == 1 ? dom(range.start)
: range.length() == 2 ? dom(range.start, range.start + 1) : range.step == 1 ? new Dom(range.start, range.stop - 1) : new Dom(range.toArray());
}
/**
* Builds an object that represents the size (length) of a 1-dimensional array.
*
* @param length
* the size (length) of the array
* @return an object that represents the size (length) of a 1-dimensional array
*/
default Size1D size(int length) {
control(length > 0, "The specified length must be strictly positive");
return Size1D.build(length);
}
/**
* Builds an object that represents the size (i.e., length of each dimension) of a 2-dimensional array.
*
* @param length0
* the size (length) of the first dimension of a 2-dimensional array
* @param length1
* the size (length) of the second dimension of a 2-dimensional array
* @return an object that represents the size (i.e., length of each dimension) of a 2-dimensional array
*/
default Size2D size(int length0, int length1) {
control(length0 > 0 && length1 > 0, "The specified lengths must be strictly positive");
return Size2D.build(length0, length1);
}
/**
* Builds an object that represents the size (i.e., length of each dimension) of a 3-dimensional array.
*
* @param length0
* the size (length) of the first dimension of a 3-dimensional array
* @param length1
* the size (length) of the second dimension of a 3-dimensional array
* @param length2
* the size (length) of the third dimension of a 3-dimensional array
* @return an object that represents the size (i.e., length of each dimension) of a 3-dimensional array
*/
default Size3D size(int length0, int length1, int length2) {
control(length0 > 0 && length1 > 0 && length2 > 0, "The specified lengths must be strictly positive");
return Size3D.build(length0, length1, length2);
}
/**
* Builds an object that represents the size (i.e., length of each dimension) of a 4-dimensional array.
*
* @param length0
* the size (length) of the first dimension of a 4-dimensional array
* @param length1
* the size (length) of the second dimension of a 4-dimensional array
* @param length2
* the size (length) of the third dimension of a 4-dimensional array
* @param length3
* the size (length) of the fourth dimension of a 4-dimensional array
* @return an object that represents the size (i.e., length of each dimension) of a 4-dimensional array
*/
default Size4D size(int length0, int length1, int length2, int length3) {
control(length0 > 0 && length1 > 0 && length2 > 0 && length3 > 0, "The specified lengths must be strictly positive");
return Size4D.build(length0, length1, length2, length3);
}
/**
* Builds an object that represents the size (i.e., length of each dimension) of a 5-dimensional array.
*
* @param length0
* the size (length) of the first dimension of a 5-dimensional array
* @param length1
* the size (length) of the second dimension of a 5-dimensional array
* @param length2
* the size (length) of the third dimension of a 5-dimensional array
* @param length3
* the size (length) of the fourth dimension of a 5-dimensional array
* @param length4
* the size (length) of the fifth dimension of a 5-dimensional array
* @return an object that represents the size (i.e., length of each dimension) of a 5-dimensional array
*/
default Size5D size(int length0, int length1, int length2, int length3, int length4) {
control(length0 > 0 && length1 > 0 && length2 > 0 && length3 > 0 && length4 > 0, "The specified lengths must be strictly positive");
return Size5D.build(length0, length1, length2, length3, length4);
}
/**
* Constructs an object {@code Range} from the specified bounds and step (difference between each two successive
* numbers).
*
* @param startInclusive
* the lower bound (inclusive) of this range
* @param endExclusive
* the upper bound (exclusive) of this range
* @param step
* the step of this range
* @return the object {@code Range} that represents an interval of values (while considering the specified step)
*
*/
default Range range(int startInclusive, int endExclusive, int step) {
return new Range(startInclusive, endExclusive, step);
}
/**
* Constructs an object {@code Range} from the specified bounds and step (difference between each two successive
* numbers).
*
* @param startInclusive
* the lower bound (inclusive) of this range
* @param endInclusive
* the upper bound (inclusive) of this range
* @param step
* the step of this range
* @return the object {@code Range} that represents an interval of values (while considering the specified step)
*
*/
default Range rangeClosed(int startInclusive, int endInclusive, int step) {
return range(startInclusive, endInclusive + 1, step);
}
/**
* Constructs an object {@code Range} from the specified bounds (using implicitly a step equal to 1).
*
* @param startInclusive
* the lower bound (inclusive) of this range
* @param endExclusive
* the upper bound (exclusive) of this range
* @return the object {@code Range} that represents an interval of values
*/
default Range range(int startInclusive, int endExclusive) {
return new Range(startInclusive, endExclusive);
}
/**
* Constructs an object {@code Range} from the specified bounds (using implicitly a step equal to 1).
*
* @param startInclusive
* the lower bound (inclusive) of this range
* @param endInclusive
* the upper bound (inclusive) of this range
* @return the object {@code Range} that represents an interval of values
*/
default Range rangeClosed(int startInclusive, int endInclusive) {
return range(startInclusive, endInclusive + 1);
}
/**
* Constructs an object {@code Range} from the specified length (using implicitly a lower bound equal to 0 and a
* step equal to 1).
*
* @param length
* the length of this range
* @return the object {@code Range} that represents an interval of values, from 0 to the specified value (excluded)
*/
default Range range(int length) {
return new Range(length);
}
// ************************************************************************
// ***** Managing Variables
// ************************************************************************
/**
* Builds a stand-alone integer variable with the specified id, domain, note (short comment) and classes. Use
* methods {@code dom()} for building integer domains. For example:
*
*
* {@code Var x = var("x", dom(range(10), "x is the number of products");}
*
*
* On our example, we build a stand-alone variable whose domain contains 10 values.
*
* @param id
* the id (unique name) of the variable
* @param dom
* the integer domain of the variable
* @param note
* a short comment about the variable
* @param classes
* the tags (possibly, none) associated with the variable
* @return a stand-alone integer variable
*/
default Var var(String id, Dom dom, String note, TypeClass... classes) {
Var x = imp().buildVarInteger(id, dom);
if (x != null)
imp().varEntities.newVarAloneEntity(id, x, note, classes);
return x;
}
/**
* Builds a stand-alone integer variable with the specified id, domain and classes. Use methods {@code dom()} for
* building integer domains. For example:
*
*
* {@code Var x = var("x", dom(range(10));}
*
*
* On our example, we build a stand-alone variable whose domain contains 10 values.
*
* @param id
* the id (unique name) of the variable
* @param dom
* the integer domain of the variable
* @param classes
* the tags (possibly, none) associated with the variable
* @return a stand-alone integer variable
*/
default Var var(String id, Dom dom, TypeClass... classes) {
return var(id, dom, null, classes);
}
/**
* Builds a 1-dimensional array of integer variables with the specified id, size, note (short comment) and classes.
* Use Method {@code size(int)} for building the size (length) of the array. The specified function {@code f}
* associates an integer domain with each variable at index {@code i} of the array. In case the specified function
* {@code f} return the value {@code null}, the variable is not built. In the following example, the first five
* variables have a domain containing 10 values whereas the next five variables have a domain containing two values
* only:
*
*
* {@code Var[] = array("x", size(10), i -> i < 5 ? dom(range(10)) : dom(0,1),"x[i] is the number of carrots eaten by the ith rabbit");}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the length of the array
* @param f
* a function that associates an integer domain with any possible index {@code i} of a variable in the
* array
* @param note
* a short comment about the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 1-dimensional array of integer variables
*/
default Var[] array(String id, Size1D size, IntToDom f, String note, TypeClass... classes) {
Var[] t = imp().fill(id, size, f, (Var[]) Array.newInstance(imp().classVI(), size.lengths));
imp().varEntities.newVarArrayEntity(id, size, t, note, classes); // TODO indicate not same domains ?
return t;
}
/**
* Builds a 1-dimensional array of integer variables with the specified id, size, and classes. Use Method
* {@code size(int)} for building the size (length) of the array. The specified function {@code f} associates an
* integer domain with each variable at index {@code i} of the array. In case the specified function {@code f}
* return the value {@code null}, the variable is not built. In the following example, the first five variables have
* a domain containing 10 values whereas the next five variables have a domain containing two values only:
*
*
* {@code Var[] = array("x", size(10), i -> i < 5 ? dom(range(10)) : dom(0,1));}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the length of the array
* @param f
* a function that associates an integer domain with any possible index {@code i} of a variable in the
* array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 1-dimensional array of integer variables
*/
default Var[] array(String id, Size1D size, IntToDom f, TypeClass... classes) {
return array(id, size, f, null, classes);
}
/**
* Builds a 1-dimensional array of integer variables with the specified id, size, domain, note and classes. Use
* Method {@code size(int)} for building the size (length) of the array. Each variable of the array has the
* specified integer domain. In the following example, the ten variables have a domain containing 10 values:
*
*
* {@code Var[] = array("x", size(10), dom(range(10), "x[i] is the number of carrots eaten by the ith rabbit");}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the length of the array
* @param dom
* the domain of each variable in the array
* @param note
* a short comment about the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 1-dimensional array of integer variables
*/
default Var[] array(String id, Size1D size, Dom dom, String note, TypeClass... classes) {
return array(id, size, i -> dom, note, classes);
}
/**
* Builds a 1-dimensional array of integer variables with the specified id, size, domain, and classes. Use Method
* {@code size(int)} for building the size (length) of the array. Each variable of the array has the specified
* integer domain. In the following example, the ten variables have a domain containing 10 values:
*
*
* {@code Var[] = array("x", size(10), dom(range(10));}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the length of the array
* @param dom
* the domain of each variable in the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 1-dimensional array of integer variables
*/
default Var[] array(String id, Size1D size, Dom dom, TypeClass... classes) {
return array(id, size, i -> dom, null, classes);
}
/**
* Builds a 2-dimensional array of integer variables with the specified id, size, note (short comment) and classes.
* Use Method {@code size(int,int)} for building the size (length of each dimension) of the array. The specified
* function {@code f} associates an integer domain with each variable at index {@code (i,j)} of the array. In case
* the specified function {@code f} return the value {@code null}, the variable is not built. In the following
* example, some variables have a domain containing 10 values whereas others have a domain containing two values
* only:
*
*
* {@code Var[][] = array("x", size(10, 5), (i,j) -> i < j ? dom(range(10)) : dom(0,1),
* "x[i][j] is the number of forks built by the jth worker at the ith factory");}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param f
* a function that associates an integer domain with any possible index {@code (i,j)} of a variable in
* the array
* @param note
* a short comment about the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 2-dimensional array of integer variables
*/
default Var[][] array(String id, Size2D size, Intx2ToDom f, String note, TypeClass... classes) {
Var[][] m = imp().fill(id, size, f, (Var[][]) Array.newInstance(imp().classVI(), size.lengths));
imp().varEntities.newVarArrayEntity(id, size, m, note, classes); // TODO indicate not same domains somewhere ?
return m;
}
/**
* Builds a 2-dimensional array of integer variables with the specified id, size, and classes. Use Method
* {@code size(int,int)} for building the size (length of each dimension) of the array. The specified function
* {@code f} associates an integer domain with each variable at index {@code (i,j)} of the array. In case the
* specified function {@code f} return the value {@code null}, the variable is not built. In the following example,
* some variables have a domain containing 10 values whereas others have a domain containing two values only:
*
*
* {@code Var[][] = array("x", size(10, 5), (i,j) -> i < j ? dom(range(10)) : dom(0,1));}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param f
* a function that associates an integer domain with any possible index {@code (i,j)} of a variable in
* the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 2-dimensional array of integer variables
*/
default Var[][] array(String id, Size2D size, Intx2ToDom f, TypeClass... classes) {
return array(id, size, f, null, classes);
}
/**
* Builds a 2-dimensional array of integer variables with the specified id, size, domain, note (short comment) and
* classes. Use Method {@code size(int,int)} for building the size (length of each dimension) of the array. Each
* variable of the array has the specified integer domain. In the following example, all variables have a domain
* containing 10 values:
*
*
* {@code Var[][] = array("x", size(10, 5), dom(range(10)),
* "x[i][j] is the number of forks built by the jth worker at the ith factory");}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param dom
* the domain of each variable in the array
* @param note
* a short comment about the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 2-dimensional array of integer variables
*/
default Var[][] array(String id, Size2D size, Dom dom, String note, TypeClass... classes) {
return array(id, size, (i, j) -> dom, note, classes);
}
/**
* Builds a 2-dimensional array of integer variables with the specified id, size, domain, and classes. Use Method
* {@code size(int,int)} for building the size (length of each dimension) of the array. Each variable of the array
* has the specified integer domain. In the following example, all variables have a domain containing 10 values:
*
*
* {@code Var[][] = array("x", size(10, 5), dom(range(10)));}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param dom
* the domain of each variable in the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 2-dimensional array of integer variables
*/
default Var[][] array(String id, Size2D size, Dom dom, TypeClass... classes) {
return array(id, size, (i, j) -> dom, null, classes);
}
/**
* Builds a 3-dimensional array of integer variables with the specified id, size, note (short comment) and classes.
* Use Method {@code size(int,int,int)} for building the size (length of each dimension) of the array. The specified
* function {@code f} associates an integer domain with each variable at index {@code (i,j,k)} of the array. In case
* the specified function {@code f} return the value {@code null}, the variable is not built. In the following
* example, some variables have a domain containing 10 values whereas others have a domain containing two values
* only:
*
*
* {@code Var[][][] = array("x", size(10, 5, 5), (i,j,k) -> i+j == k ? dom(range(10)) : dom(0,1),
* "x[i][j][k] is something I can't reveal");}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param f
* a function that associates an integer domain with any possible index {@code (i,j,k)} of a variable in
* the array
* @param note
* a short comment about the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 3-dimensional array of integer variables
*/
default Var[][][] array(String id, Size3D size, Intx3ToDom f, String note, TypeClass... classes) {
Var[][][] m = imp().fill(id, size, f, (Var[][][]) Array.newInstance(imp().classVI(), size.lengths));
imp().varEntities.newVarArrayEntity(id, size, m, note, classes); // TODO indicate not same domains?
return m;
}
/**
* Builds a 3-dimensional array of integer variables with the specified id, size, and classes. Use Method
* {@code size(int,int,int)} for building the size (length of each dimension) of the array. The specified function
* {@code f} associates an integer domain with each variable at index {@code (i,j,k)} of the array. In case the
* specified function {@code f} return the value {@code null}, the variable is not built. In the following example,
* some variables have a domain containing 10 values whereas others have a domain containing two values only:
*
*
* {@code Var[][][] = array("x", size(10, 5, 5), (i,j,k) -> i+j == k ? dom(range(10)) : dom(0,1));}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param f
* a function that associates an integer domain with any possible index {@code (i,j,k)} of a variable in
* the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 3-dimensional array of integer variables
*/
default Var[][][] array(String id, Size3D size, Intx3ToDom f, TypeClass... classes) {
return array(id, size, f, null, classes);
}
/**
* Builds a 3-dimensional array of integer variables with the specified id, size, domain, note (short comment) and
* classes. Use Method {@code size(int,int,int)} for building the size (length of each dimension) of the array. Each
* variable of the array has the specified integer domain. In the following example, all variables have a domain
* containing 10 values:
*
*
* {@code Var[][][] = array("x", size(10, 5, 2), dom(range(10)),
* "x[i][j][k] is something I can't reveal");}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param dom
* the domain of each variable in the array
* @param note
* a short comment about the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 3-dimensional array of integer variables
*/
default Var[][][] array(String id, Size3D size, Dom dom, String note, TypeClass... classes) {
return array(id, size, (i, j, k) -> dom, note, classes);
}
/**
* Builds a 3-dimensional array of integer variables with the specified id, size, domain, and classes. Use Method
* {@code size(int,int,int)} for building the size (length of each dimension) of the array. Each variable of the
* array has the specified integer domain. In the following example, all variables have a domain containing 10
* values:
*
*
* {@code Var[][][] = array("x", size(10, 5, 2), dom(range(10)));}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param dom
* the domain of each variable in the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 3-dimensional array of integer variables
*/
default Var[][][] array(String id, Size3D size, Dom dom, TypeClass... classes) {
return array(id, size, (i, j, k) -> dom, null, classes);
}
/**
* Builds a 4-dimensional array of integer variables with the specified id, size, note (short comment) and classes.
* Use Method {@code size(int,int,int,int)} for building the size (length of each dimension) of the array. The
* specified function {@code f} associates an integer domain with each variable at index {@code (i,j,k,l)} of the
* array. In case the specified function {@code f} return the value {@code null}, the variable is not built. In the
* following example, some variables have a domain containing 10 values whereas others have a domain containing two
* values only:
*
*
* {@code Var[][][][] = array("x", size(10, 5, 5, 2), (i,j,k,l) -> i+j == k+l ? dom(range(10)) : dom(0,1),
* "x[i][j][k][l] is something I can't reveal");}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param f
* a function that associates an integer domain with any possible index {@code (i,j,k,l)} of a variable
* in the array
* @param note
* a short comment about the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 4-dimensional array of integer variables
*/
default Var[][][][] array(String id, Size4D size, Intx4ToDom f, String note, TypeClass... classes) {
Var[][][][] m = imp().fill(id, size, f, (Var[][][][]) Array.newInstance(imp().classVI(), size.lengths));
imp().varEntities.newVarArrayEntity(id, size, m, note, classes); // TODO indicate not same domains
return m;
}
/**
* Builds a 4-dimensional array of integer variables with the specified id, size, and classes. Use Method
* {@code size(int,int,int,int)} for building the size (length of each dimension) of the array. The specified
* function {@code f} associates an integer domain with each variable at index {@code (i,j,k,l)} of the array. In
* case the specified function {@code f} return the value {@code null}, the variable is not built. In the following
* example, some variables have a domain containing 10 values whereas others have a domain containing two values
* only:
*
*
* {@code Var[][][][] = array("x", size(10, 5, 5, 2), (i,j,k,l) -> i+j == k+l ? dom(range(10)) : dom(0,1));}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param f
* a function that associates an integer domain with any possible index {@code (i,j,k,l)} of a variable
* in the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 4-dimensional array of integer variables
*/
default Var[][][][] array(String id, Size4D size, Intx4ToDom f, TypeClass... classes) {
return array(id, size, f, null, classes);
}
/**
* Builds a 4-dimensional array of integer variables with the specified id, size, domain, note (short comment) and
* classes. Use Method {@code size(int,int,int,int)} for building the size (length of each dimension) of the array.
* Each variable of the array has the specified integer domain. In the following example, all variables have a
* domain containing 10 values:
*
*
* {@code Var[][][][] = array("x", size(10, 5, 2, 2), dom(range(10)),
* "x[i][j][k][l] is something I can't reveal");}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param dom
* the domain of each variable in the array
* @param note
* a short comment about the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 4-dimensional array of integer variables
*/
default Var[][][][] array(String id, Size4D size, Dom dom, String note, TypeClass... classes) {
return array(id, size, (i, j, k, l) -> dom, note, classes);
}
/**
* Builds a 4-dimensional array of integer variables with the specified id, size, domain, and classes. Use Method
* {@code size(int,int,int,int)} for building the size (length of each dimension) of the array. Each variable of the
* array has the specified integer domain. In the following example, all variables have a domain containing 10
* values:
*
*
* {@code Var[][][][] = array("x", size(10, 5, 2, 2), dom(range(10)));}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param dom
* the domain of each variable in the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 4-dimensional array of integer variables
*/
default Var[][][][] array(String id, Size4D size, Dom dom, TypeClass... classes) {
return array(id, size, (i, j, k, l) -> dom, null, classes);
}
/**
* Builds a 5-dimensional array of integer variables with the specified id, size, note (short comment) and classes.
* Use Method {@code size(int,int,int,int,int)} for building the size (length of each dimension) of the array. The
* specified function {@code f} associates an integer domain with each variable at index {@code (i,j,k,l,m)} of the
* array. In case the specified function {@code f} return the value {@code null}, the variable is not built. In the
* following example, some variables have a domain containing 10 values whereas others have a domain containing two
* values only:
*
*
* {@code Var[][][][][] = array("x", size(10, 5, 5, 2, 2), (i,j,k,l) -> i+j == k+l ? dom(range(10)) : dom(0,1),
* "x[i][j][k][l] is something I can't reveal");}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param f
* a function that associates an integer domain with any possible index {@code (i,j,k,l),m} of a variable
* in the array
* @param note
* a short comment about the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 5-dimensional array of integer variables
*/
default Var[][][][][] array(String id, Size5D size, Intx5ToDom f, String note, TypeClass... classes) {
Var[][][][][] q = imp().fill(id, size, f, (Var[][][][][]) Array.newInstance(imp().classVI(), size.lengths));
imp().varEntities.newVarArrayEntity(id, size, q, note, classes); // TODO indicate not same domains
return q;
}
/**
* Builds a 5-dimensional array of integer variables with the specified id, size, and classes. Use Method
* {@code size(int,int,int,int,int)} for building the size (length of each dimension) of the array. The specified
* function {@code f} associates an integer domain with each variable at index {@code (i,j,k,l,m)} of the array. In
* case the specified function {@code f} return the value {@code null}, the variable is not built. In the following
* example, some variables have a domain containing 10 values whereas others have a domain containing two values
* only:
*
*
* {@code Var[][][][][] = array("x", size(10, 5, 5, 2, 2), (i,j,k,l) -> i+j == k+l ? dom(range(10)) : dom(0,1));}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param f
* a function that associates an integer domain with any possible index {@code (i,j,k,l,m)} of a variable
* in the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 5-dimensional array of integer variables
*/
default Var[][][][][] array(String id, Size5D size, Intx5ToDom f, TypeClass... classes) {
return array(id, size, f, null, classes);
}
/**
* Builds a 5-dimensional array of integer variables with the specified id, size, domain, note (short comment) and
* classes. Use Method {@code size(int,int,int,int,int)} for building the size (length of each dimension) of the
* array. Each variable of the array has the specified integer domain. In the following example, all variables have
* a domain containing 10 values:
*
*
* {@code Var[][][][][] = array("x", size(10, 5, 2, 2, 2), dom(range(10)),
* "x[i][j][k][l][m] is something I can't reveal");}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param dom
* the domain of each variable in the array
* @param note
* a short comment about the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 5-dimensional array of integer variables
*/
default Var[][][][][] array(String id, Size5D size, Dom dom, String note, TypeClass... classes) {
return array(id, size, (i, j, k, l, m) -> dom, note, classes);
}
/**
* Builds a 5-dimensional array of integer variables with the specified id, size, domain, note (short comment) and
* classes. Use Method {@code size(int,int,int,int,int)} for building the size (length of each dimension) of the
* array. Each variable of the array has the specified integer domain. In the following example, all variables have
* a domain containing 10 values:
*
*
* {@code Var[][][][][] = array("x", size(10, 5, 2, 2, 2), dom(range(10)));}
*
*
* @param id
* the id (unique name) of the array
* @param size
* the size (length of each dimension) of the array
* @param dom
* the domain of each variable in the array
* @param classes
* the tags (possibly, none) associated with the array
* @return a 5-dimensional array of integer variables
*/
default Var[][][][][] array(String id, Size5D size, Dom dom, TypeClass... classes) {
return array(id, size, (i, j, k, l, m) -> dom, null, classes);
}
// ************************************************************************
// ***** Special Constraints
// ************************************************************************
/**
* Builds a disentailed integer constraint, i.e., a special constraint that always returns {@code false}.
*
* @param scp
* the scope of the constraint
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* means of method chaining.
*/
default CtrEntity ctrFalse(Var[] scp) {
return extension(scp, new int[0][], POSITIVE);
}
/**
* Builds an entailed integer constraint, i.e., a special constraint that always returns {@code true}. For example,
* it may be useful to achieve some sophisticated tasks related to some forms of consistency.
*
* @param scp
* the scope of the constraint
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* means of method chaining.
*/
default CtrEntity ctrTrue(Var[] scp) {
return extension(scp, new int[0][], NEGATIVE);
}
// ************************************************************************
// ***** Constraint intension
// ************************************************************************
/**
* Builds a constraint {@code intension} from the specified
* argument that represents the root of a syntactic tree. This method can be used with integer variables but also
* with symbolic variables (but currently, it is not allowed to have both integer and symbolic variables involved
* simultaneously). As an illustration,
*
*
* {@code
* intension(eq(x, add(y, z)))
* }
*
*
* allows us to post: x = y+z
*
* @param tree
* a syntactic tree
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining.
*/
default CtrEntity intension(XNodeParent tree) {
return imp().intension(tree);
}
/**
* Returns the root of a syntactic tree built with the unary operator abs
applied to the specified
* operand. For example, one possible call is abs(sub(x,y))
that represents |x-y|
*
* @param operand
* an object that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent abs(Object operand) {
return XNodeParent.abs(operand);
}
/**
* Returns the root of a syntactic tree built with the unary operator neg
applied to the specified
* operand. For example, one possible call is neg(add(x,y))
that represents -(x+y)
*
* @param operand
* an object that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent neg(Object operand) {
return XNodeParent.neg(operand);
}
/**
* Returns the root of a syntactic tree built with the unary operator sqr
applied to the specified
* operand. For example, one possible call is sqr(x)
that represents x*x
*
* @param operand
* an object that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent sqr(Object operand) {
return XNodeParent.sqr(operand);
}
/**
* Returns the root of a syntactic tree built with the operator add
applied to the specified operands.
* For example, one possible call is add(x,y,z)
that represents x+y+z
*
* @param operands
* a sequence of operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent add(Object... operands) {
return XNodeParent.add(operands);
}
/**
* Returns the root of a syntactic tree built with the binary operator sub
applied to the specified
* operands. For example, one possible call is sub(x,y)
that represents x-y
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent sub(Object operand1, Object operand2) {
return XNodeParent.sub(operand1, operand2);
}
/**
* Returns the root of a syntactic tree built with the operator mul
applied to the specified operands.
* For example, one possible call is mul(x,y)
that represents x*y
*
* @param operands
* a sequence of operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent mul(Object... operands) {
return XNodeParent.mul(operands);
}
/**
* Returns the root of a syntactic tree built with the binary operator div
applied to the specified
* operands. For example, one possible call is div(x,y)
that represents x/y
(integer
* division)
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent div(Object operand1, Object operand2) {
return XNodeParent.div(operand1, operand2);
}
/**
* Returns the root of a syntactic tree built with the binary operator mod
applied to the specified
* operands. For example, one possible call is mod(x,2)
that represents x%2
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent mod(Object operand1, Object operand2) {
return XNodeParent.mod(operand1, operand2);
}
/**
* Returns the root of a syntactic tree built with the binary operator pow
applied to the specified
* operands. For example, one possible call is pow(x,3)
that represents x^3
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent pow(Object operand1, Object operand2) {
return XNodeParent.pow(operand1, operand2);
}
/**
* Returns the root of a syntactic tree built with the operator min
applied to the specified operands.
* For example, one possible call is min(x,y,z)
*
* @param operands
* a sequence of operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent min(Object... operands) {
return XNodeParent.min(operands);
}
/**
* Returns the root of a syntactic tree built with the operator max
applied to the specified operands.
* For example, one possible call is max(x,y,z)
.
*
* @param operands
* a sequence of operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent max(Object... operands) {
return XNodeParent.max(operands);
}
/**
* Returns the root of a syntactic tree built with the binary operator dist
applied to the specified
* operands. For example, one possible call is dist(x,y)
that represents |x-y|
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent dist(Object operand1, Object operand2) {
return XNodeParent.dist(operand1, operand2);
}
/**
* Returns the root of a syntactic tree built with the binary operator lt
applied to the specified
* operands. For example, one possible call is lt(x,10
that represents x<10
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent lt(Object operand1, Object operand2) {
return XNodeParent.lt(operand1, operand2);
}
/**
* Returns the root of a syntactic tree built with the binary operator le
applied to the specified
* operands. For example, one possible call is le(x,10)
that represents x≤10
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent le(Object operand1, Object operand2) {
return XNodeParent.le(operand1, operand2);
}
/**
* Returns the root of a syntactic tree built with the binary operator ge
applied to the specified
* operands. For example, one possible call is ge(x,10)
that represents x≥10
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent ge(Object operand1, Object operand2) {
return XNodeParent.ge(operand1, operand2);
}
/**
* Returns the root of a syntactic tree built with the binary operator gt
applied to the specified
* operands. For example, one possible call is gt(x,10)
that represents x>10
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent gt(Object operand1, Object operand2) {
return XNodeParent.gt(operand1, operand2);
}
/**
* Returns the root of a syntactic tree built with the operator ne
applied to the specified operands.
* For example, one possible call is ne(x,y)
that represents x≠y
*
* @param operands
* a sequence of operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent ne(Object... operands) {
return XNodeParent.ne(operands);
}
/**
* Returns the root of a syntactic tree built with the operator eq
applied to the specified operands.
* For example, one possible call is eq(x,y)
that represents x=y
*
* @param operands
* a sequence of operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent eq(Object... operands) {
return XNodeParent.eq(operands);
}
/**
* Returns the root of a syntactic tree built with the operator set
applied to the specified operands.
* For example, one possible call is set(1,2,3)
that represents {1,2,3}
*
* @param operands
* a sequence of operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code XNode} that represents the node of a syntactic tree
*/
default XNode set(Object... operands) {
return XNodeParent.set(operands);
}
/**
* Returns the node of a syntactic tree built with the operator set
applied to the integers from the
* specified array. For example, if {@code t} id an array containing values 1, 2 and 3, then the call
* set(t)
represents {1,2,3}
*
* @param operands
* an array of integers
* @return an object {@code XNode} that represents the node of a syntactic tree
*/
default XNode set(int[] operands) {
return XNodeParent.set(operands);
}
/**
* Returns the root of a syntactic tree built with the operator in
applied to the specified operands.
* For example, one possible call is in(x,set(1,2,3))
that represents x∈{1,2,3}
*
* @param var
* the first operand that is typically a variable but can also can be an object {@code XNode}
* @param set
* the second operand that must have been built with the operator set
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent in(Object var, Object set) {
return XNodeParent.in(var, set);
}
/**
* Returns the root of a syntactic tree built with the operator notin
applied to the specified
* operands. For example, one possible call is notin(x,set(1,2,3))
that represents
* x∉{1,2,3}
*
* @param var
* the first operand that is typically a variable but can also can be an object {@code XNode}
* @param set
* the second operand that must have been built with the operator set
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent notin(Object var, Object set) {
return XNodeParent.notin(var, set);
}
/**
* Returns the root of a syntactic tree built with the unary operator not
applied to the specified
* operand. For example, one possible call is not(eq(x,y))
that represents ¬(x=y)
*
* @param operand
* an object that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent not(Object operand) {
return XNodeParent.not(operand);
}
/**
* Returns the root of a syntactic tree built with the operator and
applied to the specified operands.
* For example, one possible call is and(eq(x,y),lt(z,3))
that represents x=y∧z<3
*
* @param operands
* a sequence of operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code XNode} that represents the node of a syntactic tree
*/
default XNodeParent and(Object... operands) {
return operands.length == 1 && operands[0] instanceof Stream ? XNodeParent.and(((Stream>) operands[0]).toArray()) : XNodeParent.and(operands);
}
/**
* Returns the root of a syntactic tree built with the operator or
applied to the specified operands.
* For example, one possible call is or(eq(x,y),lt(z,3))
that represents x=y∨z<3
*
* @param operands
* a sequence of operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code XNode} that represents the node of a syntactic tree
*/
default XNodeParent or(Object... operands) {
return operands.length == 1 && operands[0] instanceof Stream ? XNodeParent.or(((Stream>) operands[0]).toArray()) : XNodeParent.or(operands);
}
/**
* Returns the root of a syntactic tree built with the operator xor
applied to the specified operands.
* For example, one possible call is xor(eq(x,y),lt(z,3))
that represents x=y⨁z<3
*
* @param operands
* a sequence of operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code XNode} that represents the node of a syntactic tree
*/
default XNodeParent xor(Object... operands) {
return XNodeParent.xor(operands);
}
/**
* Returns the root of a syntactic tree built with the operator iff
applied to the specified operands.
* For example, one possible call is iff(eq(x,y),lt(z,3))
that represents x=y⇔z<3
*
* @param operands
* a sequence of operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code XNode} that represents the node of a syntactic tree
*/
default XNodeParent iff(Object... operands) {
return XNodeParent.iff(operands);
}
/**
* Returns the root of a syntactic tree built with the binary operator imp
applied to the specified
* operands. For example, one possible call is imp(eq(x,y),lt(z,3)
that represents
* x=y⇒z<3
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code XNodeParent} that represents the root of a syntactic tree
*/
default XNodeParent imp(Object operand1, Object operand2) {
return XNodeParent.imp(operand1, operand2);
}
/**
* Returns the root of a syntactic tree built with the binary operator if
applied to the specified
* operands. For example, one possible call is if(eq(x,y),2,4)
that represents x=y?2:4
*
* @param operand1
* the first operand that must correspond to a Boolean expression (values 0 or 1)
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @param operand3
* the third operand that can be an integer, a variable, or an object {@code XNode}
* @return the root of a syntactic tree built from the specified operands
*/
default XNodeParent ifThenElse(Object operand1, Object operand2, Object operand3) {
return XNodeParent.ifThenElse(operand1, operand2, operand3);
}
/**
* Returns the root of a syntactic tree that represents the predicate ensuring that the specified variables are put
* in two cells of a flattened matrix (whose order is specified) at a knight distance.
*
* @param x
* a first variable
* @param y
* a second variable
* @param order
* the order of the matrix
* @return the root of a syntactic tree that represents the predicate ensuring that the specified variables are put
* in two distinct cells of a flattened matrix (whose order is specified) at a knight distance
*/
default XNodeParent knightAttack(IVar x, IVar y, int order) {
XNodeParent rowDist = dist(div(x, order), div(y, order));
XNodeParent colDist = dist(mod(x, order), mod(y, order));
return or(and(eq(rowDist, 1), eq(colDist, 2)), and(eq(rowDist, 2), eq(colDist, 1)));
}
/**
* Returns the root of a syntactic tree that represents the predicate ensuring that the specified variables are put
* in two distinct cells of a flattened matrix (whose order is specified) on the same row, column or diagonal.
*
* @param x
* a first variable
* @param y
* a second variable
* @param order
* the order of the matrix
* @return the root of a syntactic tree that represents the predicate ensuring that the specified variables are put
* in two cells of a flattened matrix (whose order is specified) at a knight distance
*/
default XNodeParent queenAttack(IVar x, IVar y, int order) {
XNodeParent rowDist = dist(div(x, order), div(y, order));
XNodeParent colDist = dist(mod(x, order), mod(y, order));
return and(ne(x, y), or(eq(mod(x, order), mod(y, order)), eq(div(x, order), div(y, order)), eq(rowDist, colDist)));
}
/**
* Builds a constraint {@code intension}, while considering
* the operator {@code lt} applied to the specified arguments. This is a modeling ease of use. As an illustration,
*
*
* {@code
* lessThan(x, y);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* intension(lt(x, y));
* }
*
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity lessThan(Object operand1, Object operand2) {
return intension(lt(operand1, operand2));
}
/**
* Builds a constraint {@code intension}, while considering
* the operator {@code le} applied to the specified arguments. This is a modeling ease of use. As an illustration,
*
*
* {@code
* lessEqual(x, y);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* intension(le(x, y));
* }
*
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity lessEqual(Object operand1, Object operand2) {
return intension(le(operand1, operand2));
}
/**
* Builds a constraint {@code intension}, while considering
* the operator {@code ge} applied to the specified arguments. This is a modeling ease of use. As an illustration,
*
*
* {@code
* greaterEqual(x, y);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* intension(ge(x, y));
* }
*
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity greaterEqual(Object operand1, Object operand2) {
return intension(ge(operand1, operand2));
}
/**
* Builds a constraint {@code intension}, while considering
* the operator {@code gt} applied to the specified arguments. This is a modeling ease of use. As an illustration,
*
*
* {@code
* greaterThan(x, y);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* intension(gt(x, y));
* }
*
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity greaterThan(Object operand1, Object operand2) {
return intension(gt(operand1, operand2));
}
/**
* Builds a constraint {@code intension}, while considering
* the operator {@code eq} applied to the specified arguments. This is a modeling ease of use. As an illustration,
*
*
* {@code
* equal(x, y);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* intension(eq(x, y));
* }
*
*
* @param operands
* the operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity equal(Object... operands) {
return intension(eq(operands));
}
/**
* Builds a constraint {@code intension}, while considering
* the operator {@code ne} applied to the specified arguments. This is a modeling ease of use. As an illustration,
*
*
* {@code
* different(x, y);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* intension(ne(x, y));
* }
*
*
* @param operands
* the operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity different(Object... operands) {
return intension(ne(operands)); // imp().different(operands);
}
@Deprecated
/**
* Call {@code different} instead.
*/
default CtrEntity notEqual(Object... operands) {
return different(operands);
}
/**
* Builds a constraint {@code intension}, while considering
* the operator {@code in} applied to the specified arguments. This is a modeling ease of use. As an illustration,
*
*
* {@code
* belong(x, set(1, 2, 3));
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* intension(in(x, set(1, 2, 3)));
* }
*
*
* @param operand1
* the first operand that can be a variable, or an object {@code XNode}
* @param operand2
* the second operand that must have been built with the operator set
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity belong(Object operand1, Object operand2) {
return intension(in(operand1, operand2));
}
@Deprecated
/**
* Call {@code implication} instead.
*/
default CtrEntity imply(Object operand1, Object operand2) {
return implication(operand1, operand2);
}
/**
* Builds a constraint {@code intension}, while considering
* the operator {@code imp} applied to the specified arguments. This is a modeling ease of use. As an illustration,
*
*
* {@code
* implication(eq(x, y), lt(z, 3));
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* intension(imp(eq(x, y), lt(z, 3)));
* }
*
*
* @param operand1
* the first operand that can be an integer, a variable, or an object {@code XNode}
* @param operand2
* the second operand that can be an integer, a variable, or an object {@code XNode}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity implication(Object operand1, Object operand2) {
return intension(imp(operand1, operand2));
}
/**
* Builds a constraint {@code intension}, while considering
* the operator {@code iff} applied to the specified arguments. This is a modeling ease of use. As an illustration,
*
*
* {@code
* equivalence(eq(x, y), lt(z, 3));
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* intension(iff(eq(x, y), lt(z, 3)));
* }
*
*
* @param operands
* the operands that can be integers, variables, or objects {@code XNode}he operands that can be
* integers, variables, or objects {@code XNode}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity equivalence(Object... operands) {
return intension(iff(operands));
}
/**
* Builds a constraint {@code intension}, while considering
* the operator {@code add} applied to the specified arguments. This is a modeling ease of use.
*
* @param operands
* the operands that can be integers, variables, or objects {@code XNode}he operands that can be
* integers, variables, or objects {@code XNode}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity conjunction(Object... operands) {
return intension(and(operands));
}
/**
* Builds a constraint {@code intension}, while considering
* the operator {@code or} applied to the specified arguments. This is a modeling ease of use.
*
* @param operands
* the operands that can be integers, variables, or objects {@code XNode}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity disjunction(Object... operands) {
return intension(or(operands));
}
/**
* Returns a stream of syntactic trees (predicates) built by applying the specified function to each variable of the
* specified array. {@code null} values in the array are discarded.
*
* @param t
* an array of variables
* @param f
* a function mapping variables into syntactic trees (predicates)
* @return a stream of syntactic trees built by applying the specified function to each variable of the specified
* array
*/
default Stream> treesFrom(IVar[] t, Function> f) {
return Stream.of(t).filter(x -> x != null).map(x -> f.apply(x));
}
/**
* Returns a stream of syntactic trees (predicates) built by applying the specified function to each integer of the
* specified stream.
*
* @param stream
* a stream of integers
* @param f
* a function mapping integers into syntactic trees (predicates)
* @return a stream of syntactic trees built by applying the specified function to each integer of the specified
* stream
*/
default Stream> treesFrom(IntStream stream, Function> f) {
return stream.mapToObj(x -> f.apply(x));
}
/**
* Returns a stream of syntactic trees (predicates) built by applying the specified function to each integer of the
* specified collection. {@code null} values in the collection are discarded.
*
* @param c
* a collection of integers
* @param f
* a function mapping integers into syntactic trees (predicates)
* @return a stream of syntactic trees built by applying the specified function to each integer of the specified
* collection
*/
default Stream> treesFrom(Collection c, Function> f) {
return treesFrom(c.stream().filter(x -> x != null).mapToInt(i -> i), f);
}
/**
* Returns a stream of syntactic trees (predicates) built by applying the specified function to each integer of the
* specified array.
*
* @param t
* an array of integers
* @param f
* a function mapping integers into syntactic trees (predicates)
* @return a stream of syntactic trees built by applying the specified function to each integer of the specified
* array
*/
default Stream> treesFrom(int[] t, Function> f) {
return treesFrom(IntStream.of(t), f);
}
/**
* Returns a stream of syntactic trees (predicates) built by applying the specified function to each integer of the
* specified range.
*
* @param r
* a range
* @param f
* a function mapping integers into syntactic trees (predicates)
* @return a stream of syntactic trees built by applying the specified function to each integer of the specified
* range
*/
default Stream> treesFrom(Range r, Function> f) {
return treesFrom(r.stream(), f);
}
// default CtrEntity post(Object leftOperand, String operator, Object rightOperand) {
// if (operator.equals("!="))
// return different(leftOperand, rightOperand);
// return null;
// }
// ************************************************************************
// ***** Converting intension to extension
// ************************************************************************
/**
* Builds a constraint {@code extension} from the specified
* syntactic tree (predicate). The specified intentional constraint is converted in extensional form.
*
* @param tree
* the root of a syntactic tree (predicate)
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrAlone extension(XNodeParent tree) {
return imp().extension(tree);
}
default CtrAlone extensionDisjunction(List> trees) {
// System.out.println("One " + Stream.of(trees).map(t -> t.toString()).collect(Collectors.joining(" ")));
return imp().extensionDisjunction(trees);
}
default CtrAlone extensionDisjunction(XNodeParent... trees) {
return extensionDisjunction(Arrays.asList(trees));
}
// ************************************************************************
// ***** Constraint extension
// ************************************************************************
/**
* Builds a constraint {@code extension} from the specified
* scope and the specified array of tuples, seen as either supports (when {@code positive} is {@code true}) or
* conflicts (when {@code positive} is {@code false}). Note that you can use constants {@code POSITIVE} and
* {@code NEGATIVE}.
*
* @param scp
* the scope of the constraint
* @param tuples
* the tuples defining the semantics of the constraint
* @param positive
* boolean value indicating if the tuples are supports or conflicts
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity extension(Var[] scp, int[][] tuples, Boolean positive) {
return imp().extension(scp, tuples, positive);
}
/**
* Builds a constraint {@code extension} from the specified
* scope and the specified array of tuples, seen as supports.
*
* @param scp
* the scope of the constraint
* @param tuples
* the tuples defining the supports of the constraint
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity extension(Var[] scp, int[]... tuples) {
return extension(scp, tuples, POSITIVE);
}
/**
* Builds a constraint {@code extension} from the specified
* scope and the specified collection of tuples, seen as either supports (when {@code positive} is {@code true}) or
* conflicts (when {@code positive} is {@code false}). Note that you can use constants {@code POSITIVE} and
* {@code NEGATIVE}.
*
* @param scp
* the scope of the constraint
* @param tuples
* the tuples defining the semantics of the constraint
* @param positive
* boolean value indicating if the tuples are supports or conflicts
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity extension(Var[] scp, Collection tuples, Boolean positive) {
return extension(scp, tuples.toArray(new int[0][]), positive);
}
/**
* Builds a constraint {@code extension} from the specified
* scope and the specified collection of tuples, seen as supports.
*
* @param scp
* the scope of the constraint
* @param tuples
* the tuples defining the supports of the constraint
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity extension(Var[] scp, Collection tuples) {
return extension(scp, tuples, POSITIVE);
}
/**
* Builds a constraint {@code extension} from the specified
* scope and the specified table, whose elements are seen as supports. An example of integer table that can be
* constructed is
*
*
* {@code
* table("(1,2,3)(2,1,1)")
* }
*
*
* For a negative table, you can write:
*
*
* {@code
* table("(1,2,3)(2,1,1)").positive(false)
* }
*
*
* @param scp
* the scope of the constraint
* @param table
* the table containing the tuples defining the supports of the constraint
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity extension(Var[] scp, Table table) {
return extension(scp, table.toArray(), table.positive);
}
/**
* Builds a unary constraint {@code extension} from the
* specified variable and the specified array of values, seen as either supports (when {@code positive} is
* {@code true}) or conflicts (when {@code positive} is {@code false}). Note that you can use constants
* {@code POSITIVE} and {@code NEGATIVE}.
*
* @param x
* the variable involved in this unary constraint
* @param values
* the values defining the semantics of the constraint
* @param positive
* boolean value indicating if the values are supports or conflicts
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity extension(Var x, int[] values, Boolean positive) {
return extension(vars(x), dub(values), positive);
}
/**
* Builds a unary constraint {@code extension} from the
* specified variable and the specified array of values, seen as supports.
*
* @param x
* the variable involved in this unary constraint
* @param values
* the values defining the semantics of the constraint
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity extension(Var x, int... values) {
return extension(x, values, POSITIVE);
}
/**
* Builds a unary constraint {@code extension} from the
* specified variable and the specified table.
*
* @param x
* the variable involved in this unary constraint
* @param table
* the table defining the semantics of the constraint
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity extension(Var x, Table table) {
return extension(vars(x), table.toArray(), table.positive);
}
// ************************************************************************
// ***** Constraint regular
// ************************************************************************
/**
* Builds a constraint {@code regular} from the specified scope
* and the specified automaton. Note that an automaton can be built as in the following example:
*
*
* {@code Transitions transitions = Transitions.parse("(q0,0,q1)(q0,2,q2)(q1,0,q3)(q2,2,q3)");
* Automaton automata = new Automaton(transitions, "q0", tuple("q2", "q3"));)}
*
*
* @param scp
* the scope of the constraint
* @param automaton
* the automaton defining the semantics of the constraint
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity regular(Var[] scp, Automaton automaton) {
return imp().regular(scp, automaton);
}
// ************************************************************************
// ***** Constraint mdd
// ************************************************************************
default CtrEntity mdd(Var[] scp, Transitions transitions) {
return imp().mdd(scp, transitions.toArray());
}
/**
* Builds a constraint {@code mdd} from the specified scope and the
* specified transitions. Note that transitions can be built as in the following example:
*
*
*
* Transitions transitions = Transitions.parse("(q0,0,q1)(q0,2,q2)(q1,0,q3)(q2,2,q3)");
*
*
*
* @param scp
* the scope of the constraint
* @param transitions
* the transitions defining the MDD, and consequently the semantics of the constraint
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity mdd(Var[] scp, Transition[] transitions) {
return imp().mdd(scp, transitions);
}
// ************************************************************************
// ***** Constraint allDifferent
// ************************************************************************
/**
* Builds a constraint {@code allDifferent} on the
* specified integer variables: the variables must all take different values.
*
* @param list
* the involved integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allDifferent(Var[] list) {
// return imp().allDifferent(imp().distinct(list));
return imp().allDifferent(imp().distinctSorted(list));
}
/**
* Builds a constraint {@code allDifferent} on the
* specified integer variables: the variables must all take different values.
*
* @param x
* a first integer variable
* @param others
* a sequence of other integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allDifferent(Var x, Var... others) {
return allDifferent((Var[]) vars(x, (Object) others));
}
/**
* Builds a constraint {@code allDifferent} on the
* specified integer variables: the variables must all take different values. Note that the specified 2-dimensional
* array of variables will be flattened (i.e., converted into a 1-dimensional array of variables). Do not mistake
* this form with {@code allDifferentList}
*
* @param list
* the involved integer variables (a 2-dimensional array)
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allDifferent(Var[]... list) {
return allDifferent(vars(list));
}
/**
* Builds a constraint {@code allDifferent} on the
* specified integer variables: the variables must all take different values. Note that the specified 3-dimensional
* array of variables will be flattened (i.e., converted into a 1-dimensional array of variables).
*
* @param list
* the involved integer variables (a 3-dimensional array)
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allDifferent(Var[][][] list) {
return allDifferent(vars(list));
}
@Deprecated
/**
* Builds a constraint {@code allDifferentExcept} on the
* specified integer variables: the variables must take different values, except those that take one of the
* specified 'exceptionnal' values.
*
* @param list
* the involved integer variables
* @param exceptValues
* the values that must be ignored
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allDifferentExcept(Var[] list, int... exceptValues) {
return allDifferent(list, exceptValues);
}
/**
* Builds a constraint {@code allDifferent} on the
* specified integer variables: the variables must take different values, except those that take one of the
* specified 'exceptional' values.
*
* @param list
* the involved integer variables
* @param exceptValues
* the values that must be ignored
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allDifferent(Var[] list, int... exceptValues) {
return imp().allDifferent(list, exceptValues);
}
/**
* Builds a constraint {@code allDifferentList} on the
* specified lists of variables: all tuples formed by the different lists must be different.
*
* @param lists
* a 2-dimensional array of variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allDifferentList(Var[]... lists) {
return imp().allDifferentList(lists);
}
/**
* Builds a constraint {@code allDifferentMatrix} on the
* specified matrix of variables. On each row and on each column, the variables must all take different values.
*
* @param matrix
* a 2-dimensional array of variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allDifferentMatrix(Var[][] matrix) {
return imp().allDifferentMatrix(matrix);
}
/**
* Builds a constraint {@code allDifferent} on the
* specified syntactic trees (predicates): the predicates, when evaluated, must all take different values.
*
* @param trees
* an array of syntactic trees (predicates)
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allDifferent(XNode[] trees) {
return imp().allDifferent(trees);
}
/**
* Builds a constraint {@code allDifferent} on the
* specified (stream of) syntactic trees (predicates): the predicates, when evaluated, must all take different
* values.
*
* @param trees
* a stream of syntactic trees (predicates)
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allDifferent(Stream> trees) {
XNode[] atrees = trees.toArray(XNode[]::new);
return imp().allDifferent(atrees);
}
// ************************************************************************
// ***** Constraint allEqual
// ************************************************************************
/**
* Builds a constraint {@code allEqual} on the specified
* integer variables: the variables must all take the same value. Basically, this is a modeling ease of use.
*
* @param list
* the involved integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allEqual(Var... list) {
return imp().allEqual(list);
}
/**
* Builds a constraint {@code allEqual} on the specified
* integer variables: the variables must all take the same value. Basically, this is a modeling ease of use. Note
* that the specified 2-dimensional array of variables will be flattened (i.e., converted into a 1-dimensional array
* of variables). Do not mistake this form with {@code allEqualList}
*
* @param list
* the involved integer variables (a 2-dimensional array)
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allEqual(Var[][] list) {
return allEqual(vars(list));
}
/**
* Builds a constraint {@code allEqualList} on the specified
* lists of variables: all tuples formed by the different lists must be equal.
*
* @param lists
* a 2-dimensional array of variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity allEqualList(Var[]... lists) {
return imp().allEqualList(lists);
}
// ************************************************************************
// ***** Constraint ordered and lex
// ************************************************************************
/**
* Builds a constraint {@code ordered} on the specified lists
* of variables: any two successive variables must respect the specified operator, while considering the specified
* lengths. We have:
*
*
* {@code for any i in 0..list.length-1, list[i] + lengths[i] list[i+1]}
*
*
* In general, the size of {@code lengths} is the size of {@code list} minus 1. But, for simplicity, it is
* authorized to have the size of {@code lengths} being equal to that of {@code list}, in which case the last value
* of the integer array is simply ignored.
*
* Basically, this constraint is a modeling ease of use.
*
* @param list
* the involved integer variables
*
* @param lengths
* the lengths used
* @param operator
* a relational operator (STRICTLY_INCREASING, INCREASING, DECREASING or STRICTLY_DECREASING)
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity ordered(Var[] list, int[] lengths, TypeOperatorRel operator) {
control(list.length == lengths.length || list.length == lengths.length + 1, "The size of list must be the size of lengths (possibly, plus 1)");
return imp().ordered(list, list.length == lengths.length ? Arrays.copyOf(lengths, list.length - 1) : lengths, operator);
}
/**
* Builds a constraint {@code ordered} on the specified lists
* of variables: any two successive variables must respect the specified operator, while considering the specified
* lengths. We have:
*
*
* {@code for any i in 0..list.length-1, list[i] + lengths[i] list[i+1]}
*
*
* In general, the size of {@code lengths} is the size of {@code list} minus 1. But, for simplicity, it is
* authorized to have the size of {@code lengths} being equal to that of {@code list}, in which case the last value
* of the integer array is simply ignored.
*
* Basically, this constraint is a modeling ease of use.
*
* @param list
* the involved integer variables
*
* @param lengths
* the lengths used
* @param operator
* a relational operator (STRICTLY_INCREASING, INCREASING, DECREASING or STRICTLY_DECREASING)
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity ordered(Var[] list, Var[] lengths, TypeOperatorRel operator) {
control(list.length == lengths.length || list.length == lengths.length + 1, "The size of list must be the size of lengths (possibly, plus 1)");
return imp().ordered(list, list.length == lengths.length ? Arrays.copyOf(lengths, list.length - 1) : lengths, operator);
}
/**
* Builds a constraint {@code ordered} on the specified lists
* of variables: any two successive variables must respect the specified operator. Basically, this is a modeling
* ease of use.
*
* @param list
* the involved integer variables
* @param operator
* a relational operator (STRICTLY_INCREASING, INCREASING, DECREASING or STRICTLY_DECREASING)
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity ordered(Var[] list, TypeOperatorRel operator) {
return ordered(list, new int[list.length - 1], operator);
}
/**
* Builds a constraint {@code ordered} on the specified lists
* of variables, while considering a strict increasing order. This is a modeling ease of use. As an illustration,
*
*
* {@code
* strictlyIncreasing(x);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* ordered(x, STRICTLY_INCREASING);
* }
*
*
* @param list
* the involved integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity strictlyIncreasing(Var... list) {
return ordered(list, STRICTLY_INCREASING);
}
/**
* Builds a constraint {@code ordered} on the specified lists
* of variables, while considering an increasing order. This is a modeling ease of use. As an illustration,
*
*
* {@code
* increasing(x);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* ordered(x, INCREASING);
* }
*
*
* @param list
* the involved integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity increasing(Var... list) {
return ordered(list, INCREASING);
}
/**
* Builds a constraint {@code ordered} on the specified lists
* of variables, while considering a decreasing order. This is a modeling ease of use. As an illustration,
*
*
* {@code
* decreasing(x);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* ordered(x, DECREASING);
* }
*
*
* @param list
* the involved integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity decreasing(Var... list) {
return ordered(list, DECREASING);
}
/**
* Builds a constraint {@code ordered} on the specified lists
* of variables, while considering a strict decreasing order. This is a modeling ease of use. As an illustration,
*
*
* {@code
* strictlydecreasing(x);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* ordered(x, STRICTLY_DeCREASING);
* }
*
*
* @param list
* the involved integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity strictlyDecreasing(Var... list) {
return ordered(list, STRICTLY_DECREASING);
}
/**
* Builds a constraint {@code lex} on the specified
* 2-dimensional array of variables: any two successive rows of variables must respect the specified operator.
* Basically, this is a modeling ease of use.
*
* @param lists
* a 2-dimensional array of integer variables
* @param operator
* a relational operator (STRICTLY_INCREASING, INCREASING, DECREASING or STRICTLY_DECREASING)
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity lex(Var[][] lists, TypeOperatorRel operator) {
return imp().lex(lists, operator);
}
/**
* Builds a constraint {@code lex} on the specified
* 2-dimensional array of variables, while considering a strict increasing order on rows. This is a modeling ease of
* use. As an illustration,
*
*
* {@code
* strictlyIncreasing(x);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* ordered(x, STRICTLY_INCREASING);
* }
*
*
* @param lists
* a 2-dimensional array of integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity strictlyIncreasing(Var[]... lists) {
return lex(lists, STRICTLY_INCREASING);
}
/**
* Builds a constraint {@code lex} on the specified
* 2-dimensional array of variables, while considering an increasing order on rows. This is a modeling ease of use.
* As an illustration,
*
*
* {@code
* increasing(x);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* ordered(x, INCREASING);
* }
*
*
* @param lists
* a 2-dimensional array of integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity increasing(Var[]... lists) {
return lex(lists, INCREASING);
}
/**
* Builds a constraint {@code lex} on the specified
* 2-dimensional array of variables, while considering a decreasing order on rows. This is a modeling ease of use.
* As an illustration,
*
*
* {@code
* decreasing(x);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* ordered(x, DeCREASING);
* }
*
*
* @param lists
* a 2-dimensional array of integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity decreasing(Var[]... lists) {
return lex(lists, DECREASING);
}
/**
* Builds a constraint {@code lex} on the specified
* 2-dimensional array of variables, while considering a strict decreasing order on rows. This is a modeling ease of
* use. As an illustration,
*
*
* {@code
* strictlyDecreasing(x);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* ordered(x, STRICTLY_DECREASING);
* }
*
*
* @param lists
* a 2-dimensional array of integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity strictlyDecreasing(Var[]... lists) {
return lex(lists, STRICTLY_DECREASING);
}
/**
* Builds a constraint {@code lexMatrix} on the specified
* matrix of variables. Any two successive rows of variables and any two successive columns of variables must
* respect the specified operator.
*
* @param matrix
* a 2-dimensional array of integer variables
* @param operator
* a relational operator (STRICTLY_INCREASING, INCREASING, DECREASING or STRICTLY_DECREASING)
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity lexMatrix(Var[][] matrix, TypeOperatorRel operator) {
return imp().lexMatrix(matrix, operator);
}
// ************************************************************************
// ***** Constraint sum
// ************************************************************************
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the specified condition.
*
* @param list
* the summed variables
* @param coeffs
* the coefficients associated with the summed variables
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, int[] coeffs, Condition condition) {
return imp().sum(list, coeffs, condition);
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the sum must respect the specified condition.
*
* @param list
* the summed variables
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, Condition condition) {
Var[] t = clean(list);
return sum(t, repeat(1, t.length), condition);
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified operator and the specified limit. As an
* illustration,
*
*
* {@code
* sum(x, t, EQ, 10);
* }
*
*
* @param list
* the summed variables
* @param coeffs
* the coefficients associated with the summed variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, int[] coeffs, TypeConditionOperatorRel op, long limit) {
control(list.length == coeffs.length, "Pb because the number of variables is different form the number of coefficients");
return sum(list, coeffs, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified operator and the specified limit. The
* coefficients are given under the form of a range. As an illustration,
*
*
* {@code
* sum(x, range(5), EQ, 10);
* }
*
*
* @param list
* the summed variables
* @param coeffs
* the range of values used as coefficients for the summed variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, Range coeffs, TypeConditionOperatorRel op, long limit) {
return sum(list, vals(coeffs), op, limit);
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the (simple) sum must respect the condition expressed by the specified operator and the specified limit. As an
* illustration,
*
*
* {@code
* sum(x, EQ, 10);
* }
*
*
* @param list
* the summed variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, TypeConditionOperatorRel op, long limit) {
return sum(list, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified operator and the specified limit. As an
* illustration,
*
*
* {@code
* sum(x, t, GT, z);
* }
*
*
* @param list
* the summed variables
* @param coeffs
* the coefficients associated with the summed variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, int[] coeffs, TypeConditionOperatorRel op, Var limit) {
control(list.length == coeffs.length, "Pb because the number of variables is different form the number of coefficients");
return sum(list, coeffs, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the (simple) sum must respect the condition expressed by the specified operator and the specified limit. As an
* illustration,
*
*
* {@code
* sum(x, GT, z);
* }
*
*
* @param list
* the summed variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, TypeConditionOperatorRel op, Var limit) {
return sum(list, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified set operator and the specified interval
* (range). As an illustration,
*
*
* {@code
* sum(x, t, IN, range(1, 4));
* }
*
*
* @param list
* the summed variables
* @param coeffs
* the coefficients associated with the summed variables
* @param op
* a set operator (IN or NOTIN)
* @param range
* a range (interval) of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, int[] coeffs, TypeConditionOperatorSet op, Range range) {
control(list.length == coeffs.length, "Pb because the number of variables is different form the number of coefficients");
return sum(list, coeffs, condition(op, range));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the (simple) sum must respect the condition expressed by the specified set operator and the specified interval
* (range). As an illustration,
*
*
* {@code
* sum(x, IN, 1, 4);
* }
*
*
* @param list
* the summed variables
* @param op
* a set operator (IN or NOTIN)
* @param range
* a range (interval) of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, TypeConditionOperatorSet op, Range range) {
return sum(list, condition(op, range));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified operator and the specified set of values.
* As an illustration,
*
*
* {@code
* sum(x, t, NOTIN, vals(1, 3, 5, 6));
* }
*
*
* @param list
* the summed variables
* @param coeffs
* the coefficients associated with the summed variables
* @param op
* a set operator (IN or NOTIN)
* @param set
* the set of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, int[] coeffs, TypeConditionOperatorSet op, int[] set) {
control(list.length == coeffs.length, "Pb because the number of variables is different form the number of coefficients");
return sum(list, coeffs, condition(op, set));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the (simple) sum must respect the condition expressed by the specified operator and the specified set of values.
* As an illustration,
*
*
* {@code
* sum(x, NOTIN, vals(1, 3, 5, 6));
* }
*
*
* @param list
* the summed variables
* @param op
* a set operator (IN or NOTIN)
* @param set
* the set of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, TypeConditionOperatorSet op, int[] set) {
return sum(list, condition(op, set));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the specified condition.
*
* @param list
* the summed variables
* @param coeffs
* the coefficients associated with the summed variables
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, Var[] coeffs, Condition condition) {
return imp().sum(list, coeffs, condition);
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified operator and the specified limit. As an
* illustration,
*
*
* {@code
* sum(x, y, LE, 100);
* }
*
*
* @param list
* the summed variables
* @param coeffs
* the coefficients associated with the summed variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, Var[] coeffs, TypeConditionOperatorRel op, long limit) {
control(list.length == coeffs.length,
"Pb because the number of variables is different form the number of coefficients: " + list.length + " vs " + coeffs.length);
return sum(list, coeffs, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified operator and the specified limit. As an
* illustration,
*
*
* {@code
* sum(x, y, LE, z);
* }
*
*
* @param list
* the summed variables
* @param coeffs
* the coefficients associated with the summed variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, Var[] coeffs, TypeConditionOperatorRel op, Var limit) {
control(list.length == coeffs.length, "Pb because the number of variables is different form the number of coefficients");
return sum(list, coeffs, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified set operator and the specified interval
* (range). As an illustration,
*
*
* {@code
* sum(x, y, IN, 1, 4);
* }
*
*
* @param list
* the summed variables
* @param coeffs
* the coefficients associated with the summed variables
* @param op
* a set operator (IN or NOTIN)
* @param range
* a range (interval) of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, Var[] coeffs, TypeConditionOperatorSet op, Range range) {
control(list.length == coeffs.length, "Pb because the number of variables is different form the number of coefficients");
return sum(list, coeffs, condition(op, range));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified operator and the specified set of values.
* As an illustration,
*
*
* {@code
* sum(x, y, NOTIN, vals(1, 3, 5, 6));
* }
*
*
* @param list
* the summed variables
* @param coeffs
* the coefficients associated with the summed variables
* @param op
* a set operator (IN or NOTIN)
* @param set
* the set of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Var[] list, Var[] coeffs, TypeConditionOperatorSet op, int[] set) {
control(list.length == coeffs.length, "Pb because the number of variables is different form the number of coefficients");
return sum(list, coeffs, condition(op, set));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the specified condition.
*
* @param trees
* an array of syntactic trees (usually, predicates)
* @param coeffs
* the coefficients associated with the syntactic trees
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(XNode[] trees, int[] coeffs, Condition condition) {
return imp().sum(trees, coeffs == null ? repeat(1, trees.length) : coeffs, condition);
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the (simple) sum must respect the specified condition.
*
* @param trees
* an array of syntactic trees (usually, predicates)
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(XNode[] trees, Condition condition) {
return sum(trees, null, condition);
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the (simple) sum must respect the condition expressed by the specified operator and the specified limit.
*
* @param trees
* an array of syntactic trees (usually, predicates)
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(XNode[] trees, TypeConditionOperatorRel op, long limit) {
return sum(trees, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified operator and the specified limit.
*
* @param trees
* an array of syntactic trees (usually, predicates)
* @param coeffs
* the coefficients associated with the syntactic trees
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(XNode[] trees, int[] coeffs, TypeConditionOperatorRel op, long limit) {
return sum(trees, coeffs, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the (simple) sum must respect the condition expressed by the specified operator and the specified limit.
*
* @param trees
* an array of syntactic trees (usually, predicates)
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(XNode[] trees, TypeConditionOperatorRel op, Var limit) {
return sum(trees, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified operator and the specified limit.
*
* @param trees
* an array of syntactic trees (usually, predicates)
* @param coeffs
* the coefficients associated with the syntactic trees
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(XNode[] trees, int[] coeffs, TypeConditionOperatorRel op, Var limit) {
return sum(trees, coeffs, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the specified condition.
*
* @param trees
* a stream of syntactic trees (usually, predicates)
* @param coeffs
* the coefficients associated with the syntactic trees
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Stream> trees, int[] coeffs, Condition condition) {
XNode[] atrees = trees.toArray(XNode[]::new);
return sum(atrees, coeffs, condition);
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the (simple) sum must respect the specified condition.
*
* @param trees
* a stream of syntactic trees (usually, predicates)
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Stream> trees, Condition condition) {
return sum(trees, null, condition);
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the (simple) sum must respect the condition expressed by the specified operator and the specified limit.
*
* @param trees
* a stream of syntactic trees (usually, predicates)
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Stream> trees, TypeConditionOperatorRel op, long limit) {
return sum(trees, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified operator and the specified limit.
*
* @param trees
* a stream of syntactic trees (usually, predicates)
* @param coeffs
* the coefficients associated with the syntactic trees
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Stream> trees, int[] coeffs, TypeConditionOperatorRel op, long limit) {
return sum(trees, coeffs, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the (simple) sum must respect the condition expressed by the specified operator and the specified limit.
*
* @param trees
* a stream of syntactic trees (usually, predicates)
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Stream> trees, TypeConditionOperatorRel op, Var limit) {
return sum(trees, condition(op, limit));
}
/**
* Builds a constraint {@code sum} from the specified arguments:
* the weighted sum must respect the condition expressed by the specified operator and the specified limit.
*
* @param trees
* a stream of syntactic trees (usually, predicates)
* @param coeffs
* the coefficients associated with the syntactic trees
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the sum is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity sum(Stream> trees, int[] coeffs, TypeConditionOperatorRel op, Var limit) {
return sum(trees, coeffs, condition(op, limit));
}
// ************************************************************************
// ***** Constraint count
// ************************************************************************
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take one of the specified values must respect the
* specified condition.
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integers
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, int[] values, Condition condition) {
return imp().count(clean(list), values, condition);
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take one of the specified values must respect the
* condition expressed by the specified operator and the specified limit. As an illustration,
*
*
* {@code
* count(x, vals(0, 1), LE, 5);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integers
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the count is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, int[] values, TypeConditionOperatorRel op, int limit) {
return count(list, values, condition(op, limit));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value must respect the condition
* expressed by the specified operator and the specified limit. As an illustration,
*
*
* {@code
* count(x, 0, LE, 5);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the count is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, int value, TypeConditionOperatorRel op, int limit) {
return count(list, vals(value), condition(op, limit));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take one of the specified values must respect the
* condition expressed by the specified operator and the specified limit. As an illustration,
*
*
* {@code
* count(x, vals(0, 1), LE, z);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integers
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the count is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, int[] values, TypeConditionOperatorRel op, Var limit) {
return count(list, values, condition(op, limit));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value must respect the condition
* expressed by the specified operator and the specified limit. As an illustration,
*
*
* {@code
* count(x, 0, LE, z);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the count is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, int value, TypeConditionOperatorRel op, Var limit) {
return count(list, vals(value), condition(op, limit));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take one of the specified values must respect the
* condition expressed by the specified set operator and the specified interval (range). As an illustration,
*
*
* {@code
* count(x, vals(0, 1), IN, 1, 4);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integers
* @param op
* a set operator (IN or NOTIN)
* @param range
* a range (interval) of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, int[] values, TypeConditionOperatorSet op, Range range) {
return count(list, values, condition(op, range));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value must respect the condition
* expressed by the specified set operator and the specified interval (range). As an illustration,
*
*
* {@code
* count(x, 0, IN, 1, 4);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @param op
* a set operator (IN or NOTIN)
* @param range
* a range (interval) of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, int value, TypeConditionOperatorSet op, Range range) {
return count(list, vals(value), condition(op, range));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take one of the specified values must respect the
* condition expressed by the specified set operator and the specified set of values. As an illustration,
*
*
* {@code
* count(x, vals(0, 1), IN, t);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integers
* @param op
* a set operator (IN or NOTIN)
* @param set
* the set of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, int[] values, TypeConditionOperatorSet op, int[] set) {
return count(list, values, condition(op, set));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value must respect the condition
* expressed by the specified set operator and the specified set of values. As an illustration,
*
*
* {@code
* count(x, 1, IN, t);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @param op
* a set operator (IN or NOTIN)
* @param set
* the set of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, int value, TypeConditionOperatorSet op, int[] set) {
return count(list, vals(value), condition(op, set));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take one of the values must respect the specified
* condition.
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integer variables
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, Var[] values, Condition condition) {
return imp().count(clean(list), clean(values), condition);
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take one of the values must respect the condition
* expressed by the specified operator and the specified limit. As an illustration,
*
*
* {@code
* count(x, y, LE, 5);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integer variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the count is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, Var[] values, TypeConditionOperatorRel op, int limit) {
return count(list, values, condition(op, limit));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the assigned value must respect the condition
* expressed by the specified operator and the specified limit. As an illustration,
*
*
* {@code
* count(x, y, LE, 5);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer variable
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the count is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, Var value, TypeConditionOperatorRel op, int limit) {
return count(list, vars(value), condition(op, limit));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take one of the values must respect the condition
* expressed by the specified operator and the specified limit. As an illustration,
*
*
* {@code
* count(x, y, LE, z);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integer variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the count is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, Var[] values, TypeConditionOperatorRel op, Var limit) {
return count(list, values, condition(op, limit));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the assigned value must respect the condition
* expressed by the specified operator and the specified limit. As an illustration,
*
*
* {@code
* count(x, y, LE, z);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer variable
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the count is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, Var value, TypeConditionOperatorRel op, Var limit) {
return count(list, vars(value), condition(op, limit));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take one of the values must respect the condition
* expressed by the specified set operator and the specified interval (range). As an illustration,
*
*
* {@code
* count(x, y, IN, 1, 4);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integer variables
* @param op
* a set operator (IN or NOTIN)
* @param range
* a range (interval) of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, Var[] values, TypeConditionOperatorSet op, Range range) {
return count(list, values, condition(op, range));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the value must respect the condition expressed
* by the specified set operator and the specified interval (range). As an illustration,
*
*
* {@code
* count(x, y, IN, 1, 4);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer variable
* @param op
* a set operator (IN or NOTIN)
* @param range
* a range (interval) of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, Var value, TypeConditionOperatorSet op, Range range) {
return count(list, vars(value), condition(op, range));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take one of the specified values must respect the
* condition expressed by the specified set operator and the specified set of values. As an illustration,
*
*
* {@code
* count(x, y, IN, t);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integer variables
* @param op
* a set operator (IN or NOTIN)
* @param set
* the set of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, Var[] values, TypeConditionOperatorSet op, int[] set) {
return count(list, values, condition(op, set));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the value must respect the condition expressed
* by the specified set operator and the specified set of values. As an illustration,
*
*
* {@code
* count(x, y, IN, t);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* a 1-dimensional array of integer variables
* @param op
* a set operator (IN or NOTIN)
* @param set
* the set of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity count(Var[] list, Var value, TypeConditionOperatorSet op, int[] set) {
return count(list, vars(value), condition(op, set));
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value is at least equal to
* {@code k}. As an illustration,
*
*
* {@code
* atLeast(x, 0, 5);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* count(x, 0, GE, 5);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @param k
* an integer
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity atLeast(Var[] list, int value, int k) {
return count(list, value, GE, k);
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value is at most equal to
* {@code k}. As an illustration,
*
*
* {@code
* atMost(x, 0, 5);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* count(x, 0, LE, 5);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @param k
* an integer
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity atMost(Var[] list, int value, int k) {
return count(list, value, LE, k);
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value is exactly {@code k}. As
* an illustration,
*
*
* {@code
* exactly(x, 0, 5);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* count(x, 0, EQ, 5);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @param k
* an integer
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity exactly(Var[] list, int value, int k) {
return count(list, value, EQ, k);
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take one of the specified values is exactly
* {@code k}. As an illustration,
*
*
* {@code
* among(x, vals(2, 3, 4), 5);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* count(x, vals(2, 3, 4), EQ, 5);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integers
* @param k
* an integer
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity among(Var[] list, int[] values, int k) {
return count(list, values, EQ, k);
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value is at least equal to
* {@code k}. As an illustration,
*
*
* {@code
* atLeast(x, 0, k);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* count(x, 0, GE, k);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @param k
* an integer variable
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity atLeast(Var[] list, int value, Var k) {
return count(list, value, GE, k);
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value is at most equal to
* {@code k}. As an illustration,
*
*
* {@code
* atMost(x, 0, k);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* count(x, 0, LE, k);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @param k
* an integer variable
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity atMost(Var[] list, int value, Var k) {
return count(list, value, LE, k);
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value is exactly {@code k}. As
* an illustration,
*
*
* {@code
* exactly(x, 0, k);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* count(x, 0, EQ, k);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @param k
* an integer variable
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity exactly(Var[] list, int value, Var k) {
return count(list, value, EQ, k);
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take one of the specified values is exactly
* {@code k}. As an illustration,
*
*
* {@code
* among(x, vals(2, 3, 4), k);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* count(x, vals(2, 3, 4), EQ, k);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integers
* @param k
* an integer variable
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity among(Var[] list, int[] values, Var k) {
return count(list, values, EQ, k);
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value is at least 1. As an
* illustration,
*
*
* {@code
* atLeast1(x, 2);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* count(x, 2, GE, 1);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity atLeast1(Var[] list, int value) {
return atLeast(list, value, 1);
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value is at most 1. As an
* illustration,
*
*
* {@code
* atMost1(x, 2);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* count(x, 2, LE, 1);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity atMost1(Var[] list, int value) {
return atMost(list, value, 1);
}
/**
* Builds a constraint {@code count} from the specified
* arguments: the number of variables in the specified list that take the specified value is exactly 1. As an
* illustration,
*
*
* {@code
* exactly1(x, 2);
* }
*
*
* is equivalent (a shortcut) to:
*
*
* {@code
* count(x, 2, EQ, 1);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity exactly1(Var[] list, int value) {
return exactly(list, value, 1);
}
// ************************************************************************
// ***** Constraint nValues
// ************************************************************************
/**
* Builds a constraint {@code nValues} from the specified
* arguments: the number of distinct values taken by variables of the specified list must respect the specified
* condition.
*
* @param list
* a 1-dimensional array of integer variables
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity nValues(Var[] list, Condition condition) {
return imp().nValues(list, condition);
}
/**
* Builds a constraint {@code nValues} from the specified
* arguments: the number of distinct values taken by variables of the specified list must respect the condition
* expressed by the specified operator and the specified limit. As an illustration,
*
*
* {@code
* nValues(x, GE, 3);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the number is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity nValues(Var[] list, TypeConditionOperatorRel op, int limit) {
return nValues(list, condition(op, limit));
}
/**
* Builds a constraint {@code nValues} from the specified
* arguments: the number of distinct values taken by variables of the specified list must respect the condition
* expressed by the specified operator and the specified limit. As an illustration,
*
*
* {@code
* nValues(x, GE, k);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the number is compared
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity nValues(Var[] list, TypeConditionOperatorRel op, Var limit) {
return nValues(list, condition(op, limit));
}
/**
* Builds a constraint {@code nValues} from the specified
* arguments: the number of distinct values taken by variables of the specified list must respect the condition
* expressed by the specified set operator and the specified interval (range). As an illustration,
*
*
* {@code
* nValues(x, IN, range(1, 3));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param op
* a set operator (IN or NOTIN)
* @param range
* a range (interval) of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity nValues(Var[] list, TypeConditionOperatorSet op, Range range) {
return nValues(list, condition(op, range));
}
/**
* Builds a constraint {@code nValues} from the specified
* arguments: the number of distinct values taken by variables of the specified list must respect the condition
* expressed by the specified set operator and the specified set of values. As an illustration,
*
*
* {@code
* nValues(x, IN, vals(2, 3, 4));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param op
* a set operator (IN or NOTIN)
* @param set
* the set of values involved in the comparison
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity nValues(Var[] list, TypeConditionOperatorSet op, int[] set) {
return nValues(list, condition(op, set));
}
/**
* Builds a constraint {@code nValues} from the specified
* arguments: the number of distinct values that are taken by variables of the specified list and that do not occur
* among those specified must respect the specified condition.
*
* @param list
* a 1-dimensional array of integer variables
* @param condition
* an object {@code condition} composed of an operator and an operand
* @param exceptValues
* a sequence of integers
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity nValues(Var[] list, Condition condition, int... exceptValues) {
return imp().nValues(list, condition);
}
/**
* Builds a constraint {@code nValues} from the specified
* arguments: the number of distinct values that are taken by variables of the specified list and that do not occur
* among those specified must respect the condition expressed by the specified operator and the specified limit. As
* an illustration,
*
*
* {@code
* nValues(x, GT, 3, exceptValue(0));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the number is compared
* @param exceptValues
* a sequence of integers
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity nValues(Var[] list, TypeConditionOperatorRel op, int limit, int... exceptValues) {
return nValues(list, condition(op, limit), exceptValues);
}
/**
* Builds a constraint {@code nValues} from the specified
* arguments: the number of distinct values that are taken by variables of the specified list and that do not occur
* among those specified must respect the condition expressed by the specified operator and the specified limit. As
* an illustration,
*
*
* {@code
* nValuesExcept(x, GT, k, exceptValue(0));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param op
* a relational operator (LT, LE, GE, GT, NE, or EQ)
* @param limit
* the right operand to which the number is compared
* @param exceptValues
* a sequence of integers
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity nValues(Var[] list, TypeConditionOperatorRel op, Var limit, int... exceptValues) {
return nValues(list, condition(op, limit), exceptValues);
}
/**
* Builds a constraint {@code nValues} from the specified
* arguments: the number of distinct values that are taken by variables of the specified list and that do not occur
* among those specified must respect the condition expressed by the specified operator and the specified interval
* (range). As an illustration,
*
*
* {@code
* nValuesExcept(x, IN, range(1, 3), exceptValue(0));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param op
* a set operator (IN or NOTIN)
* @param range
* a range (interval) of values involved in the comparison
* @param exceptValues
* a sequence of integers
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity nValues(Var[] list, TypeConditionOperatorSet op, Range range, int... exceptValues) {
return nValues(list, condition(op, range), exceptValues);
}
/**
* Builds a constraint {@code nValues} from the specified
* arguments: the number of distinct values that are taken by variables of the specified list and that do not occur
* among those specified must respect the condition expressed by the specified operator and the specified set of
* values. As an illustration,
*
*
* {@code
* nValuesExcept(x, IN, vals(1, 3, 5), exceptValue(0));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param op
* a set operator (IN or NOTIN)
* @param set
* the set of values involved in the comparison
* @param exceptValues
* a sequence of integers
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity nValues(Var[] list, TypeConditionOperatorSet op, int[] set, int... exceptValues) {
return nValues(list, condition(op, set), exceptValues);
}
/**
* Builds a constraint {@code nValues} from the specified
* arguments: at least two distinct values are assigned to the variables of the specified list.
*
* @param list
* a 1-dimensional array of integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity notAllEqual(Var... list) {
return nValues(list, condition(GT, 1));
}
// ************************************************************************
// ***** Constraint cardinality
// ************************************************************************
/**
* Builds a constraint {@code cardinality} from the
* specified arguments: when considering the sequence of values assigned to the variables of {@code list}, each
* integer in {@code values} at index {@code i} must occur a number of times {@code k_i} that respects the
* conditions imposed by the object {@code Occurrences}. These conditions can be stated as follows:
*
* - when the object {@code Occurrences} represents a simple integer {@code v}, obtained by calling Method
* {@code occursEachExactly(int)}, {@code k_i} must be exactly {@code v}
* - when the object {@code Occurrences} represents a 1-dimensional array of integers {@code t}, obtained by
* calling Method {@code occurExactly(int[])}, {@code k_i} must be exactly {@code t[i]}
* - when the object {@code OccursEachBetweeen} represents an interval of integers {@code v..w}, obtained by
* calling Method {@code occursEachBetween(int,int)}, {@code k_i} must belong to {@code v..w}
* - when the object {@code OccursBetween} represents two 1-dimensional arrays of integers {@code t1 and t2},
* obtained by calling Method {@code occurBetween(int[],int[])}, {@code k_i} must belong to
* {@code t1[i]..t2[i]}
* - when the object {@code Occurrences} represents a 1-dimensional array of integer variables {@code x}, obtained
* by calling Method {@code occurExactly(Var[])}, {@code k_i} must be the same value as {@code x[i]}
*
* Note that when the specified boolean is {@code true}, it is required that all variables in {@code list} are
* assigned a value in {@code values}.
*
* As an illustration, enforcing values 1 and 2 to occur exactly 5 times each is given by:
*
*
* {@code
* cardinality(x, vals(1, 2), true, occursEachExactly(5));
* }
*
*
* Enforcing values 1 and 2 to occur between 3 and 5 times each is given by:
*
*
* {@code
* cardinality(x, vals(1, 2), true, occursEachBetween(3, 5));
* }
*
*
* Enforcing values 1 and 2 to occur exactly y1 and y2 times, with y1 and y2 two variables, each is given by:
*
*
* {@code
* cardinality(x, vals(1, 2), true, occurExactly(y1, y2));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integers
* @param mustBeClosed
* {@code true} iff all variables of {@code list} must necessarily be assigned to a value in
* {@code values}
* @param occurrences
* an object {@code Occurrences}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cardinality(Var[] list, int[] values, boolean mustBeClosed, Occurrences occurrences) {
// controls to be added
if (occurrences instanceof OccurrencesInt)
return imp().cardinality(clean(list), values, mustBeClosed, repeat(((OccurrencesInt) occurrences).occurs, values.length));
if (occurrences instanceof OccurrencesInt1D)
return imp().cardinality(clean(list), values, mustBeClosed, ((OccurrencesInt1D) occurrences).occurs);
if (occurrences instanceof OccurrencesIntRange)
return imp().cardinality(clean(list), values, mustBeClosed, repeat(((OccurrencesIntRange) occurrences).occursMin, values.length),
repeat(((OccurrencesIntRange) occurrences).occursMax, values.length));
if (occurrences instanceof OccurrencesIntRange1D)
return imp().cardinality(clean(list), values, mustBeClosed, ((OccurrencesIntRange1D) occurrences).occursMin,
((OccurrencesIntRange1D) occurrences).occursMax);
// if (occurrences instanceof OccurrencesVar)
return imp().cardinality(clean(list), values, mustBeClosed, clean(((OccurrencesVar1D) occurrences).occurs));
}
/**
* Builds a constraint {@code cardinality} from the
* specified arguments: when considering the sequence of values assigned to the variables of {@code list}, each
* integer in {@code values} at index {@code i} must occur a number of times {@code k_i} that respects the
* conditions imposed by the object {@code Occurrences}. These conditions can be stated as follows:
*
* - when the object {@code Occurrences} represents a simple integer {@code v}, obtained by calling Method
* {@code occursEachExactly(int)}, {@code k_i} must be exactly {@code v}
* - when the object {@code Occurrences} represents a 1-dimensional array of integers {@code t}, obtained by
* calling Method {@code occurExactly(int[])}, {@code k_i} must be exactly {@code t[i]}
* - when the object {@code OccursEachBetweeen} represents an interval of integers {@code v..w}, obtained by
* calling Method {@code occursEachBetween(int,int)}, {@code k_i} must belong to {@code v..w}
* - when the object {@code OccursBetween} represents two 1-dimensional arrays of integers {@code t1 and t2},
* obtained by calling Method {@code occurBetween(int[],int[])}, {@code k_i} must belong to
* {@code t1[i]..t2[i]}
* - when the object {@code Occurrences} represents a 1-dimensional array of integer variables {@code x}, obtained
* by calling Method {@code occurExactly(Var[])}, {@code k_i} must be the same value as {@code x[i]}
*
*
* As an illustration, enforcing values 1 and 2 to occur exactly 5 times each is given by:
*
*
* {@code
* cardinality(x, vals(1, 2), occursEachExactly(5));
* }
*
*
* Enforcing values 1 and 2 to occur between 3 and 5 times each is given by:
*
*
* {@code
* cardinality(x, vals(1, 2), occursEachBetween(3, 5));
* }
*
*
* Enforcing values 1 and 2 to occur exactly y1 and y2 times, with y1 and y2 two variables, each is given by:
*
*
* {@code
* cardinality(x, vals(1, 2), occurExactly(y1, y2));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integers
* @param occurrences
* an object {@code Occurrences}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cardinality(Var[] list, int[] values, Occurrences occurrences) {
return cardinality(list, values, false, occurrences);
}
/**
* Builds a constraint {@code cardinality} from the
* specified arguments: when considering the sequence of values assigned to the variables of {@code list}, each
* integer in the range {@code values} at index {@code i} must occur a number of times {@code k_i} that respects the
* conditions imposed by the object {@code Occurrences}. These conditions can be stated as follows:
*
* - when the object {@code Occurrences} represents a simple integer {@code v}, obtained by calling Method
* {@code occursEachExactly(int)}, {@code k_i} must be exactly {@code v}
* - when the object {@code Occurrences} represents a 1-dimensional array of integers {@code t}, obtained by
* calling Method {@code occurExactly(int[])}, {@code k_i} must be exactly {@code t[i]}
* - when the object {@code OccursEachBetweeen} represents an interval of integers {@code v..w}, obtained by
* calling Method {@code occursEachBetween(int,int)}, {@code k_i} must belong to {@code v..w}
* - when the object {@code OccursBetween} represents two 1-dimensional arrays of integers {@code t1 and t2},
* obtained by calling Method {@code occurBetween(int[],int[])}, {@code k_i} must belong to
* {@code t1[i]..t2[i]}
* - when the object {@code Occurrences} represents a 1-dimensional array of integer variables {@code x}, obtained
* by calling Method {@code occurExactly(Var[])}, {@code k_i} must be the same value as {@code x[i]}
*
*
* As an illustration, enforcing values 1, 2, 3 and 4 to occur exactly 5 times each is given by:
*
*
* {@code
* cardinality(x, range(1, 4), occursEachExactly(5));
* }
*
*
* Enforcing values 1, 2, 3 and 4 to occur between 3 and 5 times each is given by:
*
*
* {@code
* cardinality(x, range(1, 4), occursEachBetween(3, 5));
* }
*
*
* Enforcing values 1, 2, 3 and 4 to occur exactly y[i] times, with y an array of variables and i the index of each
* value in turn, each is given by:
*
*
* {@code
* cardinality(x, range(1, 4), occurExactly(y));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a range of integers
* @param occurrences
* an object {@code Occurrences}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cardinality(Var[] list, Range values, Occurrences occurrences) {
return cardinality(list, vals(values), occurrences);
}
/**
* Builds a constraint {@code cardinality} from the
* specified arguments: when considering the sequence of values assigned to the variables of {@code list}, each
* integer in {@code values} at index {@code i} must occur a number of times {@code k_i} that respects the
* conditions imposed by the object {@code Occurrences}. These conditions can be stated as follows:
*
* - when the object {@code Occurrences} represents a simple integer {@code v}, obtained by calling Method
* {@code occursEachExactly(int)}, {@code k_i} must be exactly {@code v}
* - when the object {@code Occurrences} represents a 1-dimensional array of integers {@code t}, obtained by
* calling Method {@code occurExactly(int[])}, {@code k_i} must be exactly {@code t[i]}
* - when the object {@code OccursEachBetweeen} represents an interval of integers {@code v..w}, obtained by
* calling Method {@code occursEachBetween(int,int)}, {@code k_i} must belong to {@code v..w}
* - when the object {@code OccursBetween} represents two 1-dimensional arrays of integers {@code t1 and t2},
* obtained by calling Method {@code occurBetween(int[],int[])}, {@code k_i} must belong to
* {@code t1[i]..t2[i]}
* - when the object {@code Occurrences} represents a 1-dimensional array of integer variables {@code x}, obtained
* by calling Method {@code occurExactly(Var[])}, {@code k_i} must be the same value as {@code x[i]}
*
* Note that when the specified boolean is {@code true}, it is required that all variables in {@code list} are
* assigned a value in {@code values}.
*
* As an illustration, enforcing values from array y to occur exactly 5 times each is given by:
*
*
* {@code
* cardinality(x, y, true, occursEachExactly(5));
* }
*
*
* Enforcing values from array y to occur between 3 and 5 times each is given by:
*
*
* {@code
* cardinality(x, y, true, occursEachBetween(3, 5));
* }
*
*
* Enforcing value y[i] to occur exactly z[i] times is given by:
*
*
* {@code
* cardinality(x, y, true, occurExactly(z));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integer variables
* @param mustBeClosed
* {@code true} iff all variables of {@code list} must necessarily be assigned to a value in
* {@code values}
* @param occurrences
* an object {@code Occurrences}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cardinality(Var[] list, Var[] values, boolean mustBeClosed, Occurrences occurrences) {
// controls to be added
if (occurrences instanceof OccurrencesInt)
return imp().cardinality(clean(list), clean(values), mustBeClosed, repeat(((OccurrencesInt) occurrences).occurs, values.length));
if (occurrences instanceof OccurrencesInt1D)
return imp().cardinality(clean(list), clean(values), mustBeClosed, ((OccurrencesInt1D) occurrences).occurs);
if (occurrences instanceof OccurrencesIntRange)
return imp().cardinality(clean(list), clean(values), mustBeClosed, repeat(((OccurrencesIntRange) occurrences).occursMin, values.length),
repeat(((OccurrencesIntRange) occurrences).occursMax, values.length));
if (occurrences instanceof OccurrencesIntRange1D)
return imp().cardinality(clean(list), clean(values), mustBeClosed, ((OccurrencesIntRange1D) occurrences).occursMin,
((OccurrencesIntRange1D) occurrences).occursMax);
// if (occurrences instanceof OccurrencesVar)
return imp().cardinality(clean(list), clean(values), mustBeClosed, clean(((OccurrencesVar1D) occurrences).occurs));
}
/**
* Builds a constraint {@code cardinality} from the
* specified arguments: when considering the sequence of values assigned to the variables of {@code list}, each
* integer in {@code values} at index {@code i} must occur a number of times {@code k_i} that respects the
* conditions imposed by the object {@code Occurrences}. These conditions can be stated as follows:
*
* - when the object {@code Occurrences} represents a simple integer {@code v}, obtained by calling Method
* {@code occursEachExactly(int)}, {@code k_i} must be exactly {@code v}
* - when the object {@code Occurrences} represents a 1-dimensional array of integers {@code t}, obtained by
* calling Method {@code occurExactly(int[])}, {@code k_i} must be exactly {@code t[i]}
* - when the object {@code OccursEachBetweeen} represents an interval of integers {@code v..w}, obtained by
* calling Method {@code occursEachBetween(int,int)}, {@code k_i} must belong to {@code v..w}
* - when the object {@code OccursBetween} represents two 1-dimensional arrays of integers {@code t1 and t2},
* obtained by calling Method {@code occurBetween(int[],int[])}, {@code k_i} must belong to
* {@code t1[i]..t2[i]}
* - when the object {@code Occurrences} represents a 1-dimensional array of integer variables {@code x}, obtained
* by calling Method {@code occurExactly(Var[])}, {@code k_i} must be the same value as {@code x[i]}
*
*
* As an illustration, enforcing values from array y to occur exactly 5 times each is given by:
*
*
* {@code
* cardinality(x, y, occursEachExactly(5));
* }
*
*
* Enforcing values from array y to occur between 3 and 5 times each is given by:
*
*
* {@code
* cardinality(x, y, occursEachBetween(3, 5));
* }
*
*
* Enforcing value y[i] to occur exactly z[i] times is given by:
*
*
* {@code
* cardinality(x, y, occurrences(z));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param values
* a 1-dimensional array of integer variables
* @param occurs
* an object {@code Occurrences}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cardinality(Var[] list, Var[] values, Occurrences occurs) {
return cardinality(list, values, false, occurs);
}
// ************************************************************************
// ***** Constraint maximum
// ************************************************************************
/**
* Builds a constraint {@code maximum} from the specified
* arguments: the maximum of the values assigned to the variables of {@code list} must respect the specified
* condition. Note that the array {@code list} is cleaned (i.e., {@code null} values are discarded).
* As an illustration, enforcing the maximum value of x to be strictly less than 10 is given by:
*
*
* {@code
* maximum(x, condition(LT, 10));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param condition
* an object {@code Condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity maximum(Var[] list, Condition condition) {
return imp().maximum(clean(list), condition);
}
/**
* Builds a constraint {@code maximum} from the specified
* arguments: the maximum of the values assigned to the variables of {@code list} must be equal to the value
* assigned to the variable {@code value}. Note that the array {@code list} is cleaned (i.e., {@code null} values
* are discarded).
* As an illustration, enforcing the maximum value of x to be m is given by:
*
*
* {@code
* maximum(x, m);
* }
*
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer variable
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity maximum(Var[] list, Var value) {
return maximum(list, condition(EQ, value));
}
/**
* Builds a constraint {@code maximum} from the specified
* arguments: the maximum of the values assigned to the variables of {@code list} must be the value assigned to the
* variable of {@code list} at {@code index.variable}. Note that {@code index.rank} indicates if
* {@code index.variable} must be:
*
* - the smallest valid number (FIRST), meaning that {@code index.variable} must refer to the first variable in
* {@code list} with maximum value
* - the greatest valid number (LAST), meaning that {@code index.variable} must refer to the last variable in
* {@code list} with maximum value
* - or any valid number (ANY), meaning that {@code index.variable} can refer to any variable in {@code list} with
* maximum value.
*
* Important: for building an object {@code Index}, use Method {@code index(Var)} or Method
* {@code index(Var,TypeRank)}.
*
* As an illustration, enforcing i to be the index of any variable in x (indexing being started at 0) with maximum
* value is given by:
*
*
* {@code
* maximum(x, index(i));
* }
*
*
* Enforcing i to be the index of the first variable in x (indexing being started at 0) with maximum value is given
* by:
*
*
* {@code
* maximum(x, index(i, FIRST));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param index
* an object wrapping the variable corresponding to the index of a variable in {@code list} with maximum
* value
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity maximum(Var[] list, Index index) {
return imp().maximum(list, 0, index.var, index.rank);
}
/**
* Builds a constraint {@code maximum} from the specified
* arguments: the maximum of the values assigned to the variables of {@code list} must be the value assigned to the
* variable of {@code list} at {@code index.variable} and besides this value must respect the specified condition.
* Note that {@code startIndex.value} indicates the number used to access the first variable in {@code list} whereas
* {@code index.rank} indicates if {@code index.variable} must be:
*
* - the smallest valid number (FIRST), meaning that {@code index.variable} must refer to the first variable in
* {@code list} with maximum value
* - the greatest valid number (LAST), meaning that {@code index.variable} must refer to the last variable in
* {@code list} with maximum value
* - or any valid number (ANY), meaning that {@code index.variable} can refer to any variable in {@code list} with
* maximum value.
*
* Important: for building an object {@code StartIndex}, use Method {@code startIndex(int)}, for building an
* object {@code Index}, use Method {@code index(Var)} or Method {@code index(Var,TypeRank)} and for building an
* object {@code Condition} use methods {@code condition()}.
*
* As an illustration, enforcing i to be the index of any variable in x (indexing being started at 1) with maximum
* value strictly greater than 10 is given by:
*
*
* {@code
* maximum(x, startIndex(1), index(i), condition(GT, 10));
* }
*
*
* Enforcing i to be the index of the first variable in x (indexing being started at 10) with maximum value strictly
* greater than 10 is given by:
*
*
* {@code
* maximum(x, startIndex(10), index(i, FIRST), condition(GT, 10));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param startIndex
* the number used to access the first variable in {@code list}
* @param index
* an object wrapping the variable corresponding to the index of a variable in {@code list} with maximum
* value
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity maximum(Var[] list, int startIndex, Index index, Condition condition) {
return imp().maximum(list, startIndex, index.var, index.rank, condition);
}
/**
* Builds a constraint {@code maximum} from the specified
* arguments: the maximum of the values assigned to the variables of {@code list} must be the value assigned to the
* variable of {@code list} at {@code index.variable} and besides this value must respect the specified condition.
* Note that indexing starts at 0 and that {@code index.rank} indicates if {@code index.variable} must be:
*
* - the smallest valid number (FIRST), meaning that {@code index.variable} must refer to the first variable in
* {@code list} with maximum value
* - the greatest valid number (LAST), meaning that {@code index.variable} must refer to the last variable in
* {@code list} with maximum value
* - or any valid number (ANY), meaning that {@code index.variable} can refer to any variable in {@code list} with
* maximum value.
*
* Important: for building an object {@code Index}, use Method {@code index(Var)} or Method
* {@code index(Var,TypeRank)} and for building an object {@code Condition} use methods {@code condition()}.
*
* As an illustration, enforcing i to be the index of any variable in x (indexing starting at 0, by default) with
* maximum value strictly greater than 10 is given by:
*
*
* {@code
* maximum(x, at(i), condition(GT, 10));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param index
* the variable corresponding to the index of a variable in {@code list} with maximum value
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity maximum(Var[] list, Var index, Condition condition) {
return maximum(list, 0, index(index), condition);
}
// ************************************************************************
// ***** Constraint minimum
// ************************************************************************
/**
* Builds a constraint {@code minimum} from the specified
* arguments: the minimum of the values assigned to the variables of {@code list} must respect the specified
* condition. Note that the array {@code list} is cleaned (i.e., {@code null} values are discarded).
* As an illustration, enforcing the minimum value of x to be strictly less than 10 is given by:
*
*
* {@code
* minimum(x, condition(LT, 10));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param condition
* an object {@code Condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity minimum(Var[] list, Condition condition) {
return imp().minimum(list, condition);
}
/**
* Builds a constraint {@code minimum} from the specified
* arguments: the minimum of the values assigned to the variables of {@code list} must be equal to the value
* assigned to the variable {@code value}. Note that the array {@code list} is cleaned (i.e., {@code null} values
* are discarded).
* As an illustration, enforcing the minimum value of x to be m is given by:
*
*
* {@code
* minimum(x, m);
* }
*
*
*
* @param list
* a 1-dimensional array of integer variables
* @param value
* an integer variable
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity minimum(Var[] list, Var value) {
return minimum(list, condition(EQ, value));
}
/**
* Builds a constraint {@code minimum} from the specified
* arguments: the minimum of the values assigned to the variables of {@code list} must be the value assigned to the
* variable of {@code list} at {@code index.variable}. Note that {@code index.rank} indicates if
* {@code index.variable} must be:
*
* - the smallest valid number (FIRST), meaning that {@code index.variable} must refer to the first variable in
* {@code list} with minimum value
* - the greatest valid number (LAST), meaning that {@code index.variable} must refer to the last variable in
* {@code list} with minimum value
* - or any valid number (ANY), meaning that {@code index.variable} can refer to any variable in {@code list} with
* minimum value.
*
* Important: for building an object {@code Index}, use Method {@code index(Var)} or Method
* {@code index(Var,TypeRank)}.
*
* As an illustration, enforcing i to be the index of any variable in x (indexing being started at 0) with minimum
* value is given by:
*
*
* {@code
* minimum(x, index(i));
* }
*
*
* Enforcing i to be the index of the first variable in x (indexing being started at 0) with minimum value is given
* by:
*
*
* {@code
* minimum(x, index(i, FIRST));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param index
* an object wrapping the variable corresponding to the index of a variable in {@code list} with minimum
* value
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity minimum(Var[] list, Index index) {
return imp().minimum(list, 0, index.var, index.rank);
}
/**
* Builds a constraint {@code minimum} from the specified
* arguments: the minimum of the values assigned to the variables of {@code list} must be the value assigned to the
* variable of {@code list} at {@code index.variable} and besides this value must respect the specified condition.
* Note that {@code startIndex.value} indicates the number used to access the first variable in {@code list} whereas
* {@code index.rank} indicates if {@code index.variable} must be:
*
* - the smallest valid number (FIRST), meaning that {@code index.variable} must refer to the first variable in
* {@code list} with minimum value
* - the greatest valid number (LAST), meaning that {@code index.variable} must refer to the last variable in
* {@code list} with minimum value
* - or any valid number (ANY), meaning that {@code index.variable} can refer to any variable in {@code list} with
* minimum value.
*
* Important: for building an object {@code StartIndex}, use Method {@code startIndex(int)}, for building an
* object {@code Index}, use Method {@code index(Var)} or Method {@code index(Var,TypeRank)} and for building an
* object {@code Condition} use methods {@code condition()}.
*
* As an illustration, enforcing i to be the index of any variable in x (indexing being started at 1) with minimum
* value strictly greater than 10 is given by:
*
*
* {@code
* minimum(x, startIndex(1), index(i), condition(GT, 10));
* }
*
*
* Enforcing i to be the index of the first variable in x (indexing being started at 10) with minimum value strictly
* greater than 10 is given by:
*
*
* {@code
* minimum(x, startIndex(10), index(i, FIRST), condition(GT, 10));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param startIndex
* the number used to access the first variable in {@code list}
* @param index
* an object wrapping the variable corresponding to the index of a variable in {@code list} with minimum
* value
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity minimum(Var[] list, int startIndex, Index index, Condition condition) {
return imp().minimum(list, startIndex, index.var, index.rank, condition);
}
/**
* Builds a constraint {@code minimum} from the specified
* arguments: the minimum of the values assigned to the variables of {@code list} must be the value assigned to the
* variable of {@code list} at {@code index.variable} and besides this value must respect the specified condition.
* Note that indexing starts at 0 and that {@code index.rank} indicates if {@code index.variable} must be:
*
* - the smallest valid number (FIRST), meaning that {@code index.variable} must refer to the first variable in
* {@code list} with minimum value
* - the greatest valid number (LAST), meaning that {@code index.variable} must refer to the last variable in
* {@code list} with minimum value
* - or any valid number (ANY), meaning that {@code index.variable} can refer to any variable in {@code list} with
* minimum value.
*
* Important: for building an object {@code Index}, use Method {@code index(Var)} or Method
* {@code index(Var,TypeRank)} and for building an object {@code Condition} use methods {@code condition()}.
*
* As an illustration, enforcing i to be the index of any variable in x (indexing starting at 0, by default) with
* minimum value strictly greater than 10 is given by:
*
*
* {@code
* minimum(x, index(i), condition(GT, 10));
* }
*
*
* Enforcing i to be the index of the first variable in x (indexing starting at 0, by default) with minimum value
* strictly greater than 10 is given by:
*
*
* {@code
* minimum(x, index(i, FIRST), condition(GT, 10));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param index
* the variable corresponding to the index of a variable in {@code list} with minimum value
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity minimum(Var[] list, Var index, Condition condition) {
return minimum(list, 0, index(index), condition);
}
// ************************************************************************
// ***** Constraint element
// ************************************************************************
default CtrEntity element(Var[] list, Condition condition) {
return imp().element(list, condition);
}
default CtrEntity element(Var[] list, int startIndex, Index index, Condition condition) {
return imp().element(list, startIndex, index.var, index.rank, condition);
}
default CtrEntity element(Var[] list, Var index, Condition condition) {
return element(list, startIndex(0), index(index), condition);
}
default CtrEntity element(int[] list, int startIndex, Index index, Condition condition) {
return imp().element(list, startIndex, index.var, index.rank, condition);
}
default CtrEntity element(int[] list, Var index, Condition condition) {
return element(list, startIndex(0), index(index), condition);
}
default CtrEntity element(int[][] matrix, int startRowIndex, Var rowIndex, int startColIndex, Var colIndex, Condition condition) {
return imp().element(matrix, startRowIndex, rowIndex, startColIndex, colIndex, condition);
}
// ************************************************************************
// ***** Constraint channel
// ************************************************************************
/**
* Builds a constraint {@code channel} from the specified
* arguments: the value {@code j} is assigned to the ith variable of {@code list} iff the value {@code i} is
* assigned to the jth variable of {@code list}. Note that {@code startIndex.value} indicates the number used to
* access the first variable in {@code list}. Important: for building an object {@code StartIndex}, use
* Method {@code startIndex(int)}
*
* As an illustration, enforcing a channeling constraint on x (indexing starting at 1) is given by:
*
*
* {@code
* channel(x, startIndex(1));
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param startIndex
* the number used to access the first variable in {@code list}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity channel(Var[] list, int startIndex) {
return imp().channel(list, startIndex);
}
/**
* Builds a constraint {@code channel} from the specified
* arguments: the value {@code j} is assigned to the ith variable of {@code list} iff the value {@code i} is
* assigned to the jth variable of {@code list}. Note that indexing starts at 0 (default value).
*
* As an illustration, enforcing a channeling constraint on x (indexing starting at 0, by default) is given by:
*
*
* {@code
* channel(x);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity channel(Var[] list) {
return channel(list, startIndex(0));
}
/**
* Builds a constraint {@code channel} from the specified
* arguments: assuming for simplicity that indexing start at 0, the value {@code j} is assigned to the ith variable
* of {@code list1} iff the value {@code i} is assigned to the jth variable of {@code list2}.
*
*
* {@code list1[i] = j => list2|j] = i}
*
*
* The size of the array {@code list1} must be less than or equal to the size of {@code list2}. Still, assuming for
* simplicity that indexing starts at 0, When both arrays have the same size, we have:
*
*
* {@code list1[i] = j <=> list2|j] = i}
*
*
*
* Note that {@code startIndex1.value} indicates the number used to access the first variable in {@code list1}, and
* similarly {@code startIndex2.value} indicates the number used to access the first variable in {@code list2}.
* Important: for building an object {@code StartIndex}, use Method {@code startIndex(int)}
*
* As an illustration, enforcing a channeling constraint between x and y (indexing starting at 1 and 0,
* respectively) is given by:
*
*
* {@code
* channel(x, startIndex(1), y, startIndex(0));
* }
*
*
* @param list1
* a first 1-dimensional array of integer variables
* @param startIndex1
* the number used to access the first variable in {@code list1}
* @param list2
* a second 1-dimensional array of integer variables
* @param startIndex2
* the number used to access the first variable in {@code list2}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity channel(Var[] list1, int startIndex1, Var[] list2, int startIndex2) {
control(list1.length <= list2.length, "The size of the first list must be less than or equal to the size of the second list");
return imp().channel(list1, startIndex1, list2, startIndex2);
}
/**
* Builds a constraint {@code channel} from the specified
* arguments. The value {@code j} is assigned to the ith variable of {@code list1} implies that the value {@code i}
* is assigned to the jth variable of {@code list2}.
*
*
* {@code list1[i] = j => list2|j] = i}
*
*
* The size of the array {@code list1} must be less than or equal to the size of {@code list2}. When both arrays
* have the same size, we have:
*
*
* {@code list1[i] = j <=> list2|j] = i}
*
*
* Note that indexing starts at 0 (default value).
*
* As an illustration, enforcing a channeling constraint between x and y (indexing starting at 0, by default) is
* given by:
*
*
* {@code
* channel(x, y);
* }
*
*
* @param list1
* a first 1-dimensional array of integer variables
* @param list2
* a second 1-dimensional array of integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity channel(Var[] list1, Var[] list2) {
return channel(list1, startIndex(0), list2, startIndex(0));
}
/**
* Builds a constraint {@code channel} from the specified
* arguments: the value {@code i} is assigned to {@code value} iff only the ith variable of {@code list} is assigned
* the value 1 (0 is the value assigned to the other variables of {@code list}). Note that {@code list} must only
* contain variables with domain 0/1 and that {@code startIndex.value} indicates the number used to access the first
* variable in {@code list}. Important: for building an object {@code StartIndex}, use Method
* {@code startIndex(int)}
*
* As an illustration, enforcing a channeling constraint between x (indexing starting at 1) and v is given by:
*
*
* {@code
* channel(x, startIndex(1), v);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @param startIndex
* the number used to access the first variable in {@code list}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity channel(Var[] list, int startIndex, Var value) {
return imp().channel(list, startIndex, value);
}
/**
* Builds a constraint {@code channel} from the specified
* arguments: the value {@code i} is assigned to {@code value} iff only the ith variable of {@code list} is assigned
* the value 1 (0 is the value assigned to the other variables of {@code list}). Note that {@code list} must only
* contain variables with domain 0/1 and that indexing starts at 0 (default value).
*
* As an illustration, enforcing a channeling constraint between x (indexing starting at 0, by default) and v is
* given by:
*
*
* {@code
* channel(x, v);
* }
*
*
* @param list
* a 1-dimensional array of integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity channel(Var[] list, Var value) {
return channel(list, startIndex(0), value);
}
// ************************************************************************
// ***** Constraint stretch
// ************************************************************************
default CtrEntity stretch(Var[] list, int[] values, int[] widthsMin, int[] widthsMax, int[][] patterns) {
return imp().stretch(list, values, widthsMin, widthsMax, patterns);
}
default CtrEntity stretch(Var[] list, int[] values, int[] widthsMin, int[] widthsMax) {
return stretch(list, values, widthsMin, widthsMax, null);
}
// ************************************************************************
// ***** Constraint noOverlap
// ************************************************************************
/**
* Builds a constraint {@code noOverlap} from the specified
* arguments: we are given a set of tasks, defined by their origins and durations (lengths), which must not overlap.
* When {@code zeroIgnored} is {@code false}, it means that zero-length tasks cannot be packed anywhere (cannot
* overlap with other tasks).
*
* As an illustration, enforcing that tasks defined by x (origins) and t (lengths) must not overlap is given by:
*
*
* {@code
* noOverlap(x, t, true);
* }
*
*
* @param origins
* a 1-dimensional array of integer variables
* @param lengths
* a 1-dimensional array of integer integers
* @param zeroIgnored
* indicates if tasks of length 0 can be ignored
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity noOverlap(Var[] origins, int[] lengths, boolean zeroIgnored) {
return imp().noOverlap(origins, lengths, zeroIgnored);
}
/**
* Builds a constraint {@code noOverlap} from the specified
* arguments: we are given a set of tasks, defined by their origins and durations (lengths), which must not overlap.
* Note that zero-length tasks are simply ignored (default value).
*
* As an illustration, enforcing that tasks defined by x (origins) and t (lengths) must not overlap is given by:
*
*
* {@code
* noOverlap(x, t);
* }
*
*
* @param origins
* a 1-dimensional array of integer variables
* @param lengths
* a 1-dimensional array of integer integers
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity noOverlap(Var[] origins, int... lengths) {
return noOverlap(origins, lengths, true);
}
/**
* Builds a constraint {@code noOverlap} from the specified
* arguments: we are given two tasks, defined by their origins and durations (lengths), which must not overlap.
*
* As an illustration, enforcing that the task of origin x1 and length 5 must not overlap with the task of origin x2
* and length 3 is given by:
*
*
* {@code
* noOverlap(x1, x2, 5, 3);
* }
*
*
* @param x1
* a first integer variable, denoting the origin of a first task
* @param x2
* a second integer variable, denoting the origin of a second task
* @param length1
* the length associated with the first variable
* @param length2
* the length associated with the second variable
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity noOverlap(Var x1, Var x2, int length1, int length2) {
control(length1 > 0 && length2 > 0, "It is not relevant to have a length which is not strictly positive");
return noOverlap(vars(x1, x2), vals(length1, length2));
}
/**
* Builds a constraint {@code noOverlap} from the specified
* arguments: we are given a set of tasks, defined by their origins and durations (lengths), which must not overlap.
* When {@code zeroIgnored} is {@code false}, it means that zero-length tasks cannot be packed anywhere (cannot
* overlap with other tasks).
*
* As an illustration, enforcing that tasks defined by x (origins) and y (lengths) must not overlap is given by:
*
*
* {@code
* noOverlap(x, y, true);
* }
*
*
* @param origins
* a 1-dimensional array of integer variables
* @param lengths
* a 1-dimensional array of integer variables
* @param zeroIgnored
* indicates if tasks of length 0 can be ignored
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity noOverlap(Var[] origins, Var[] lengths, boolean zeroIgnored) {
return imp().noOverlap(origins, lengths, zeroIgnored);
}
/**
* Builds a constraint {@code noOverlap} from the specified
* arguments: we are given a set of tasks, defined by their origins and durations (lengths), which must not overlap.
* Note that zero-length tasks are simply ignored (default value).
*
* As an illustration, enforcing that tasks defined by x (origins) and y (lengths) must not overlap is given by:
*
*
* {@code
* noOverlap(x, y);
* }
*
*
* @param origins
* a 1-dimensional array of integer variables
* @param lengths
* a 1-dimensional array of integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity noOverlap(Var[] origins, Var... lengths) {
return noOverlap(origins, lengths, true);
}
/**
* Builds a constraint {@code noOverlap} from the specified
* arguments: we are given two tasks, defined by their origins and durations (lengths), which must not overlap. Note
* that zero-length tasks are simply ignored (default value).
*
* As an illustration, enforcing that the task of origin x1 and length y1 must not overlap with the task of origin
* x2 and length y2 is given by:
*
*
* {@code
* noOverlap(x1, x2, y1, y2);
* }
*
*
* @param x1
* a first integer variable, denoting the origin of a first task
* @param x2
* a second integer variable, denoting the origin of a second task
* @param length1
* the length associated with {@code x1}
* @param length2
* the length associated with {@code x2}
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity noOverlap(Var x1, Var x2, Var length1, Var length2) {
return noOverlap(vars(x1, x2), vars(length1, length2));
}
/**
* Builds a constraint {@code noOverlap} from the specified
* arguments: we are given a set of tasks, defined by their origins and durations (lengths), which must not overlap.
* The ith task is defined by its origin {@code origins[i][j]} wrt the jth axis and its length {@code lengths[i][j]}
* wrt the jth axis. When {@code zeroIgnored} is {@code false}, it means that tasks with a length 0 on some axis
* cannot be packed anywhere (cannot overlap with other tasks).
*
* As an illustration, enforcing that tasks defined by x (origins) and y (lengths) must not overlap is given by:
*
*
* {@code
* noOverlap(x, y, true);
* }
*
*
* @param origins
* a 2-dimensional array of integer variables
* @param lengths
* a 2-dimensional array of integer integers
* @param zeroIgnored
* indicates if tasks of length 0 (on any axis) can be ignored
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity noOverlap(Var[][] origins, int[][] lengths, boolean zeroIgnored) {
return imp().noOverlap(origins, lengths, zeroIgnored);
}
/**
* Builds a constraint {@code noOverlap} from the specified
* arguments: we are given a set of tasks, defined by their origins and durations (lengths), which must not overlap.
* The ith task is defined by its origin {@code origins[i][j]} wrt the jth axis and its length {@code lengths[i][j]}
* wrt the jth axis. Note that tasks of length 0 on some axis are simply ignored (default value).
*
* As an illustration, enforcing that tasks defined by x (origins) and y (lengths) must not overlap is given by:
*
*
* {@code
* noOverlap(x, y);
* }
*
*
* @param origins
* a 2-dimensional array of integer variables
* @param lengths
* a 2-dimensional array of integer integers
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity noOverlap(Var[][] origins, int[]... lengths) {
return noOverlap(origins, lengths, true);
}
/**
* Builds a constraint {@code noOverlap} from the specified
* arguments: we are given a set of tasks, defined by their origins and durations (lengths), which must not overlap.
* The ith task is defined by its origin {@code origins[i][j]} wrt the jth axis and its length {@code lengths[i][j]}
* wrt the jth axis. When {@code zeroIgnored} is {@code false}, it means that tasks with a length 0 on some axis
* cannot be packed anywhere (cannot overlap with other tasks).
*
* As an illustration, enforcing that tasks defined by x (origins) and y (lengths) must not overlap is given by:
*
*
* {@code
* noOverlap(x, y, true);
* }
*
*
* @param origins
* a 2-dimensional array of integer variables
* @param lengths
* a 2-dimensional array of integer variables
* @param zeroIgnored
* indicates if tasks of length 0 (on any axis) can be ignored
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity noOverlap(Var[][] origins, Var[][] lengths, boolean zeroIgnored) {
return imp().noOverlap(origins, lengths, zeroIgnored);
}
/**
* Builds a constraint {@code noOverlap} from the specified
* arguments: we are given a set of tasks, defined by their origins and durations (lengths), which must not overlap.
* The ith task is defined by its origin {@code origins[i][j]} wrt the jth axis and its length {@code lengths[i][j]}
* wrt the jth axis. Note that tasks of length 0 on some axis are simply ignored (default value).
*
* As an illustration, enforcing that tasks defined by x (origins) and y (lengths) must not overlap is given by:
*
*
* {@code
* noOverlap(x, y);
* }
*
*
* @param origins
* a 2-dimensional array of integer variables
* @param lengths
* a 2-dimensional array of integer variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity noOverlap(Var[][] origins, Var[]... lengths) {
return noOverlap(origins, lengths, true);
}
// ************************************************************************
// ***** Constraint cumulative
// ************************************************************************
/**
* Builds a constraint {@code cumulative} from the
* specified arguments: we are given a set of tasks, defined by their origins, durations (lengths), ends and
* heights. The constraint enforces that at each point in time, the summed height of tasks that overlap that point,
* respects a numerical condition. When the operator "le" is used, this corresponds to not exceeding a given limit.
*
* @param origins
* the origin (beginning) of each task
* @param lengths
* the duration (length) of each task
* @param ends
* the end of each task
* @param heights
* the height of each task
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cumulative(Var[] origins, int[] lengths, Var[] ends, int[] heights, Condition condition) {
return imp().cumulative(origins, lengths, ends, heights, condition);
}
/**
* Builds a constraint {@code cumulative} from the
* specified arguments: we are given a set of tasks, defined by their origins, durations (lengths), and heights. The
* constraint enforces that at each point in time, the summed height of tasks that overlap that point, respects a
* numerical condition. When the operator "le" is used, this corresponds to not exceeding a given limit.
*
* @param origins
* the origin (beginning) of each task
* @param lengths
* the duration (length) of each task
* @param heights
* the height of each task
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cumulative(Var[] origins, int[] lengths, int[] heights, Condition condition) {
return cumulative(origins, lengths, null, heights, condition);
}
/**
* Builds a constraint {@code cumulative} from the
* specified arguments: we are given a set of tasks, defined by their origins, durations (lengths), and heights. The
* constraint enforces that at each point in time, the summed height of tasks that overlap that point does not
* exceed the specified limit.
*
* @param origins
* the origin (beginning) of each task
* @param lengths
* the duration (length) of each task
* @param heights
* the height of each task
* @param limit
* the limit that must not be exceeded
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cumulative(Var[] origins, int[] lengths, int[] heights, long limit) {
return cumulative(origins, lengths, null, heights, condition(LE, limit));
}
/**
* Builds a constraint {@code cumulative} from the
* specified arguments: we are given a set of tasks, defined by their origins, durations (lengths), ends and
* heights. The constraint enforces that at each point in time, the summed height of tasks that overlap that point,
* respects a numerical condition. When the operator "le" is used, this corresponds to not exceeding a given limit.
*
* @param origins
* the origin (beginning) of each task
* @param lengths
* the duration (length) of each task
* @param ends
* the end of each task
* @param heights
* the height of each task
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cumulative(Var[] origins, Var[] lengths, Var[] ends, int[] heights, Condition condition) {
return imp().cumulative(origins, lengths, ends, heights, condition);
}
/**
* Builds a constraint {@code cumulative} from the
* specified arguments: we are given a set of tasks, defined by their origins, durations (lengths), and heights. The
* constraint enforces that at each point in time, the summed height of tasks that overlap that point, respects a
* numerical condition. When the operator "le" is used, this corresponds to not exceeding a given limit.
*
* @param origins
* the origin (beginning) of each task
* @param lengths
* the duration (length) of each task
* @param heights
* the height of each task
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cumulative(Var[] origins, Var[] lengths, int[] heights, Condition condition) {
return cumulative(origins, lengths, null, heights, condition);
}
/**
* Builds a constraint {@code cumulative} from the
* specified arguments: we are given a set of tasks, defined by their origins, durations (lengths), and heights. The
* constraint enforces that at each point in time, the summed height of tasks that overlap that point does not
* exceed the specified limit.
*
* @param origins
* the origin (beginning) of each task
* @param lengths
* the duration (length) of each task
* @param heights
* the height of each task
* @param limit
* the limit that must not be exceeded
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cumulative(Var[] origins, Var[] lengths, int[] heights, long limit) {
return cumulative(origins, lengths, null, heights, condition(LE, limit));
}
/**
* Builds a constraint {@code cumulative} from the
* specified arguments: we are given a set of tasks, defined by their origins, durations (lengths), ends and
* heights. The constraint enforces that at each point in time, the summed height of tasks that overlap that point,
* respects a numerical condition. When the operator "le" is used, this corresponds to not exceeding a given limit.
*
* @param origins
* the origin (beginning) of each task
* @param lengths
* the duration (length) of each task
* @param ends
* the end of each task
* @param heights
* the height of each task
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cumulative(Var[] origins, int[] lengths, Var[] ends, Var[] heights, Condition condition) {
return imp().cumulative(origins, lengths, ends, heights, condition);
}
/**
* Builds a constraint {@code cumulative} from the
* specified arguments: we are given a set of tasks, defined by their origins, durations (lengths), and heights. The
* constraint enforces that at each point in time, the summed height of tasks that overlap that point, respects a
* numerical condition. When the operator "le" is used, this corresponds to not exceeding a given limit.
*
* @param origins
* the origin (beginning) of each task
* @param lengths
* the duration (length) of each task
* @param heights
* the height of each task
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cumulative(Var[] origins, int[] lengths, Var[] heights, Condition condition) {
return cumulative(origins, lengths, null, heights, condition);
}
/**
* Builds a constraint {@code cumulative} from the
* specified arguments: we are given a set of tasks, defined by their origins, durations (lengths), and heights. The
* constraint enforces that at each point in time, the summed height of tasks that overlap that point does not
* exceed the specified limit.
*
* @param origins
* the origin (beginning) of each task
* @param lengths
* the duration (length) of each task
* @param heights
* the height of each task
* @param limit
* the limit that must not be exceeded
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cumulative(Var[] origins, int[] lengths, Var[] heights, long limit) {
return cumulative(origins, lengths, null, heights, condition(LE, limit));
}
/**
* Builds a constraint {@code cumulative} from the
* specified arguments: we are given a set of tasks, defined by their origins, durations (lengths), ends and
* heights. The constraint enforces that at each point in time, the summed height of tasks that overlap that point,
* respects a numerical condition. When the operator "le" is used, this corresponds to not exceeding a given limit.
*
* @param origins
* the origin (beginning) of each task
* @param lengths
* the duration (length) of each task
* @param ends
* the end of each task
* @param heights
* the height of each task
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cumulative(Var[] origins, Var[] lengths, Var[] ends, Var[] heights, Condition condition) {
return imp().cumulative(origins, lengths, ends, heights, condition);
}
/**
* Builds a constraint {@code cumulative} from the
* specified arguments: we are given a set of tasks, defined by their origins, durations (lengths), and heights. The
* constraint enforces that at each point in time, the summed height of tasks that overlap that point, respects a
* numerical condition. When the operator "le" is used, this corresponds to not exceeding a given limit.
*
* @param origins
* the origin (beginning) of each task
* @param lengths
* the duration (length) of each task
* @param heights
* the height of each task
* @param condition
* an object {@code condition} composed of an operator and an operand
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cumulative(Var[] origins, Var[] lengths, Var[] heights, Condition condition) {
return cumulative(origins, lengths, null, heights, condition);
}
/**
* Builds a constraint {@code cumulative} from the
* specified arguments: we are given a set of tasks, defined by their origins, durations (lengths), and heights. The
* constraint enforces that at each point in time, the summed height of tasks that overlap that point does not
* exceed the specified limit.
*
* @param origins
* the origin (beginning) of each task
* @param lengths
* the duration (length) of each task
* @param heights
* the height of each task
* @param limit
* the limit that must not be exceeded
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity cumulative(Var[] origins, Var[] lengths, Var[] heights, long limit) {
return cumulative(origins, lengths, null, heights, condition(LE, limit));
}
// ************************************************************************
// ***** Constraint circuit
// ************************************************************************
/**
* Builds a constraint {@code circuit} from the specified
* arguments.
*
* @param list
* an array of variables
* @param startIndex
* the index used to refer to the first variable of the array
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity circuit(Var[] list, int startIndex) {
return imp().circuit(list, startIndex);
}
/**
* Builds a constraint {@code circuit} on the specified array
* of variables. Note that 0 is the index used to refer to the first variable of the array.
*
* @param list
* an array of variables
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity circuit(Var[] list) {
return circuit(list, 0);
}
/**
* Builds a constraint {@code circuit} from the specified
* arguments.
*
* @param list
* an array of variables
* @param startIndex
* the index used to refer to the first variable of the array
* @param size
* the size of the circuit
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity circuit(Var[] list, int startIndex, int size) {
return imp().circuit(list, startIndex, size);
}
/**
* Builds a constraint {@code circuit} from the specified
* arguments.
*
* @param list
* an array of variables
* @param startIndex
* the index used to refer to the first variable of the array
* @param size
* the size of the circuit
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity circuit(Var[] list, int startIndex, Var size) {
return imp().circuit(list, startIndex, size);
}
/**
* Builds a constraint {@code circuit} from the specified
* arguments. Note that 0 is the index used to refer to the first variable of the array
*
* @param list
* an array of variables
* @param size
* the size of the circuit
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity circuit(Var[] list, Var size) {
return circuit(list, 0, size);
}
// ************************************************************************
// ***** Constraint clause
// ************************************************************************
/**
* Builds a constraint {@code clause} from the specified arguments. For each variable and its corresponding phase
* (i.e., at the same index), a literal is present in the clause: a positive literal when the phase is {@code true}
* and a negative literal when the phase is {@code false}.
*
* @param list
* an array of variables
* @param phases
* an array of boolean values
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity clause(Var[] list, Boolean[] phases) {
control(Stream.of(list).noneMatch(x -> x == null) && Stream.of(phases).noneMatch(x -> x == null), "No null values is allowed in the specified arrays.");
return imp().clause(list, phases);
}
/**
* Builds a constraint {@code clause} from the specified arguments. For each variable, a literal is present in the
* clause: a positive literal when the variable belongs to the first specified array and a negative literal when the
* variable belongs to the second specified array.
*
* @param pos
* a first array of variables involved in positive literals
* @param neg
* a second array of variables involved in negative literals
* @return an object {@code CtrEntity} that wraps the built constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity clause(Var[] pos, Var[] neg) {
control(Stream.of(pos).noneMatch(x -> x == null) && Stream.of(neg).noneMatch(x -> x == null), "No null values is allowed in the specified arrays.");
Boolean[] phases = IntStream.range(0, pos.length + neg.length).mapToObj(i -> (Boolean) (i < pos.length)).toArray(Boolean[]::new);
return clause(vars(pos, (Object) neg), phases);
}
// ************************************************************************
// ***** Constraint instantiation
// ************************************************************************
/**
* Builds a constraint {@code instantiation}, assigning
* each specified variable with its corresponding value. For example:
*
*
* {@code
* instantiation(x, t);
* }
*
*
* @param list
* an array of variables
* @param values
* an array of integers
* @return an object {@code CtrEntity} that wraps the build constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity instantiation(Var[] list, int... values) {
list = list == null ? list : clean(list);
control(list == null && values.length == 0 || list.length == values.length, "The length of list is different from the length of values");
if (values.length == 0)
return imp().dummyConstraint("A constraint instantiation with a scope of 0 variable.");
return imp().instantiation(list, values);
}
/**
* Builds a constraint {@code instantiation}, assigning
* each specified variable with its corresponding value (from the range). For example:
*
*
* {@code
* instantiation(x, range(10));
* }
*
*
* @param list
* an array of variables
* @param values
* a range of values
* @return an object {@code CtrEntity} that wraps the build constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity instantiation(Var[] list, Range values) {
return instantiation(list, values.toArray());
}
/**
* Builds a constraint {@code instantiation}, assigning
* each specified variable with its corresponding value in the specified stream.
*
* @param list
* an array of variables
* @param values
* a stream of integers
* @return an object {@code CtrEntity} that wraps the build constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity instantiation(Var[] list, IntStream values) {
return instantiation(list, values.toArray());
}
/**
* Builds a constraint {@code instantiation}, assigning
* each specified variable with its corresponding value in the specified collection.
*
* @param list
* an array of variables
* @param values
* a collection of integers
* @return an object {@code CtrEntity} that wraps the build constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity instantiation(Var[] list, Collection values) {
return instantiation(list, values.stream().mapToInt(i -> i));
}
/**
* Builds a constraint {@code instantiation}, assigning
* each specified variable with the specified value. For example:
*
*
* {@code
* instantiation(x, 0);
* }
*
*
* @param list
* an array of variables
* @param value
* an integer
* @return an object {@code CtrEntity} that wraps the build constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity instantiation(Var[] list, int value) {
list = list == null ? list : clean(list);
if (list == null || list.length == 0)
return imp().dummyConstraint("A constraint instantiation with a scope of 0 variable.");
return instantiation(list, repeat(value, list.length));
}
/**
* Builds a constraint {@code instantiation}, assigning
* each specified variable with its corresponding value. For example:
*
*
* {@code
* instantiation(x, t);
* }
*
*
* @param list
* a stream of variables
* @param values
* a stream of integers
* @return an object {@code CtrEntity} that wraps the build constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity instantiation(Stream list, IntStream values) {
return instantiation(vars(list), values.toArray());
}
/**
* Builds a constraint {@code instantiation}, assigning
* each specified variable at index {@code i} with its corresponding value at index {@code i}, provided that the
* specified predicate accepts {@code i}. For example:
*
*
* {@code
* instantiation(x, t, i -> i % 2 == 0);
* }
*
*
* @param list
* a 1-dimensional array of variables
* @param values
* a 1-dimensional array of integers
* @param p
* a predicate allowing us to test if a variable (and its value) at index {@code i} must be considered
*
* @return an object {@code CtrEntity} that wraps the build constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity instantiation(Var[] list, int[] values, Intx1Predicate p) {
if (list == null || values == null)
return imp().dummyConstraint("A constraint instantiation with a scope of 0 variable.");
return instantiation(select(list, p), selectFromIndexing(values, p));
}
/**
* Builds a constraint {@code instantiation}, assigning
* each specified variable at index {@code (i,j)} with its corresponding value at index {@code (i,j)}, provided that
* the specified predicate accepts {@code (i,j)}. For example:
*
*
* {@code
* instantiation(x, t, (i, j) -> i < j);
* }
*
*
* @param list
* a 2-dimensional array of variables
* @param values
* a 2-dimensional array of integers
* @param p
* a predicate allowing us to test if a variable (and its value) at index {@code (i,j)} must be
* considered
* @return an object {@code CtrEntity} that wraps the build constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity instantiation(Var[][] list, int[][] values, Intx2Predicate p) {
if (list == null || values == null)
return imp().dummyConstraint("A constraint instantiation with a scope of 0 variable.");
return instantiation(select(list, p), selectFromIndexing(values, p));
}
/**
* Builds a constraint {@code instantiation}, assigning
* each specified variable at index {@code (i,j,k)} with its corresponding value at index {@code (i,j,k)}, provided
* that the specified predicate accepts {@code (i,j,k)}. For example:
*
*
* {@code
* instantiation(x, t, (i, j, k) -> i == j + k);
* }
*
*
* @param list
* a 3-dimensional array of variables
* @param values
* a 3-dimensional array of integers
* @param p
* a predicate allowing us to test if a variable (and its value) at index {@code (i,j,k)} must be
* considered
* @return an object {@code CtrEntity} that wraps the build constraint and allows us to provide note and tags by
* method chaining
*/
default CtrEntity instantiation(Var[][][] list, int[][][] values, Intx3Predicate p) {
return instantiation(select(list, p), selectFromIndexing(values, p));
}
// ************************************************************************
// ***** Meta-Constraint slide
// ************************************************************************
/**
* Builds a meta-constraint {@code slide} from the specified
* arguments. The specified template represents a sliding constraint over the specified variables. More precisely,
* for each value of the specified range, the specified template is called to generate a constraint using the
* specified variables. For example:
*
*
* {@code
* slide(x, range(nCards - 1), i -> extension(vars(x[i], x[i + 1]), tuples));
* }
*
*
* @param list
* a 1-dimensional array of variables
* @param range
* a range of values
* @param template
* a lambda used to generate a constraint for each value of the range
* @return an object {@code CtrEntity} that wraps the build meta-constraint and allows us to provide note and tags
* by method chaining
*/
default CtrEntity slide(IVar[] list, Range range, IntFunction template) {
control(range.start == 0 && range.length() > 0, "Bad form of range");
return imp().slide(list, range, template);
}
// ************************************************************************
// ***** Meta-Constraint ifThen
// ************************************************************************
/**
* Builds a meta-constraint {@code ifThen} from the two specified constraints. This is equivalent to:
*
*
* {@code
* if c1 then
* c2
* }
*
*
* @param c1
* a first constraint (used as condition of the alternative)
* @param c2
* a second constraint (used as "then" part of the alternative)
* @return an object {@code CtrEntity} that wraps the built meta-constraint and allows us to provide note and tags
* by method chaining
*/
default CtrEntity ifThen(CtrEntity c1, CtrEntity c2) {
return imp().ifThen(c1, c2);
}
// ************************************************************************
// ***** Meta-Constraint ifThenElse
// ************************************************************************
/**
* Builds a meta-constraint {@code ifThenElse} from the three specified constraints. This is equivalent to:
*
*
* {@code
* if c1 then
* c2
* else
* c3
* }
*
*
* @param c1
* a first constraint (used as condition of the alternative)
* @param c2
* a second constraint (used as "then" part of the alternative)
* @param c3
* a third constraint (used as "else" part of the alternative)
* @return an object {@code CtrEntity} that wraps the built meta-constraint and allows us to provide note and tags
* by method chaining
*/
default CtrEntity ifThenElse(CtrEntity c1, CtrEntity c2, CtrEntity c3) {
return imp().ifThenElse(c1, c2, c3);
}
// ************************************************************************
// ***** Managing objectives
// ************************************************************************
/**
* Builds an objective (function) to minimize: the value of
* the specified variable.
*
* @param x
* a variable
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity minimize(IVar x) {
return imp().minimize(x);
}
/**
* Builds an objective (function) to maximize: the value of
* the specified variable.
*
* @param x
* a variable
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity maximize(IVar x) {
return imp().maximize(x);
}
default ObjEntity minimize(XNode tree) {
return imp().minimize(tree);
}
default ObjEntity maximize(XNode tree) {
return imp().maximize(tree);
}
/**
* Builds an objective (function) to minimize: the objective
* is defined by the specified type on the specified array of variables. For example:
*
*
* {@code
* minimize(SUM, x, y, z);
* }
*
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity minimize(TypeObjective type, IVar... list) {
IVar[] vars = vars(list); // need to do that because the cast is automatically removed by Eclipse
return imp().minimize(type, vars);
}
/**
* Builds an objective (function) to minimize: the objective
* is defined by the specified type on the specified 2-dimensional array of variables that will be flattened (i.e.,
* converted into a 1-dimensional array of variables).
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity minimize(TypeObjective type, IVar[][] list) {
return minimize(type, vars(list));
}
/**
* Builds an objective (function) to minimize: the objective
* is defined by the specified type on the specified 3-dimensional array of variables that will be flattened (i.e.,
* converted into a 1-dimensional array of variables).
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity minimize(TypeObjective type, IVar[][][] list) {
return minimize(type, vars(list));
}
/**
* Builds an objective (function) to maximize: the objective
* is defined by the specified type on the specified array of variables. For example:
*
*
* {@code
* maximize(SUM, x, y, z);
* }
*
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity maximize(TypeObjective type, IVar... list) {
IVar[] vars = vars(list); // need to do that because the cast is automatically removed by Eclipse
return imp().maximize(type, vars);
}
/**
* Builds an objective (function) to maximize: the objective
* is defined by the specified type on the specified 2-dimensional array of variables that will be flattened (i.e.,
* converted into a 1-dimensional array of variables).
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity maximize(TypeObjective type, IVar[][] list) {
return maximize(type, vars(list));
}
/**
* Builds an objective (function) to maximize: the objective
* is defined by the specified type on the specified 3-dimensional array of variables that will be flattened (i.e.,
* converted into a 1-dimensional array of variables).
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity maximize(TypeObjective type, IVar[][][] list) {
return maximize(type, vars(list));
}
/**
* Builds an objective (function) to minimize: the objective
* is defined by the specified type on the specified array of variables, each of them being given a coefficient. For
* example:
*
*
* {@code
* minimize(SUM, vars(x, y, z), vals(1, 2, 1));
* }
*
*
* @param type
* the type of tProblemAPIhe objective
* @param list
* the involved variables
* @param coeffs
* the coefficients associated with the variables
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity minimize(TypeObjective type, IVar[] list, int[] coeffs) {
control(list.length == coeffs.length, "Size of list and coeffs are different");
return imp().minimize(type, list, coeffs);
}
/**
* Builds an objective (function) to minimize: the objective
* is defined by the specified type on the specified 2-dimensional array of variables, each of them being given a
* coefficient. The arrays will be flattened (i.e., converted into 1-dimensional arrays).
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @param coeffs
* the coefficients associated with the variables
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity minimize(TypeObjective type, IVar[][] list, int[][] coeffs) {
return minimize(type, vars(list), vals((Object) coeffs));
}
/**
* Builds an objective (function) to minimize: the objective
* is defined by the specified type on the specified 2-dimensional array of variables, each of them being given a
* coefficient. The arrays will be flattened (i.e., converted into 1-dimensional arrays). Only variables at index
* accepted by the specified predicate are considered. For example:
*
*
* {@code
* minimize(SUM, x, t, (i, j) -> i < j);
* }
*
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @param coeffs
* the coefficients associated with the variables
* @param p
* a predicate allowing us to test if a variable (and its coefficient) at index {@code (i,j)} must be
* considered.
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity minimize(TypeObjective type, IVar[][] list, int[][] coeffs, Intx2Predicate p) {
return minimize(type, select(list, p), selectFromIndexing(coeffs, p));
}
/**
* Builds an objective (function) to minimize: the objective
* is defined by the specified type on the specified 3-dimensional array of variables, each of them being given a
* coefficient. The arrays will be flattened (i.e., converted into 1-dimensional arrays).
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @param coeffs
* the coefficients associated with the variables
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity minimize(TypeObjective type, IVar[][][] list, int[][][] coeffs) {
return minimize(type, vars(list), vals((Object) coeffs));
}
/**
* Builds an objective (function) to minimize: the objective
* is defined by the specified type on the specified 3-dimensional array of variables, each of them being given a
* coefficient. The arrays will be flattened (i.e., converted into 1-dimensional arrays). Only variables at index
* accepted by the specified predicate are considered. For example:
*
*
* {@code
* minimize(SUM, x, t, (i, j, k) -> i < j + k);
* }
*
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @param coeffs
* the coefficients associated with the variables
* @param p
* a predicate allowing us to test if a variable (and its coefficient) at index {@code (i,j,k)} must be
* considered
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity minimize(TypeObjective type, IVar[][][] list, int[][][] coeffs, Intx3Predicate p) {
return minimize(type, select(list, p), selectFromIndexing(coeffs, p));
}
/**
* Builds an objective (function) to maximize: the objective
* is defined by the specified type on the specified array of variables, each of them being given a coefficient. For
* example:
*
*
* {@code
* maximize(SUM, vars(x, y, z), vals(1, 2, 1));
* }
*
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @param coeffs
* the coefficients associated with the variables
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity maximize(TypeObjective type, IVar[] list, int[] coeffs) {
control(list.length == coeffs.length, "Size of list and coeffs are different");
return imp().maximize(type, list, coeffs);
}
/**
* Builds an objective (function) to maximize: the objective
* is defined by the specified type on the specified 2-dimensional array of variables, each of them being given a
* coefficient. The arrays will be flattened (i.e., converted into 1-dimensional arrays).
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @param coeffs
* the coefficients associated with the variables
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity maximize(TypeObjective type, IVar[][] list, int[][] coeffs) {
return maximize(type, vars(list), vals((Object) coeffs));
}
/**
* Builds an objective (function) to maximize: the objective
* is defined by the specified type on the specified 2-dimensional array of variables, each of them being given a
* coefficient. The arrays will be flattened (i.e., converted into 1-dimensional arrays). Only variables at index
* accepted by the specified predicate are considered. For example:
*
*
* {@code
* maximize(SUM, x, t, (i, j) -> i < j);
* }
*
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @param coeffs
* the coefficients associated with the variables
* @param p
* a predicate allowing us to test if a variable (and its coefficient) at index {@code (i,j)} must be
* considered.
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity maximize(TypeObjective type, IVar[][] list, int[][] coeffs, Intx2Predicate p) {
return maximize(type, select(list, p), selectFromIndexing(coeffs, p));
}
/**
* Builds an objective (function) to maximize: the objective
* is defined by the specified type on the specified 3-dimensional array of variables, each of them being given a
* coefficient. The arrays will be flattened (i.e., converted into 1-dimensional arrays).
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @param coeffs
* the coefficients associated with the variables
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity maximize(TypeObjective type, IVar[][][] list, int[][][] coeffs) {
return maximize(type, vars(list), vals((Object) coeffs));
}
/**
* Builds an objective (function) to maximize: the objective
* is defined by the specified type on the specified 3-dimensional array of variables, each of them being given a
* coefficient. The arrays will be flattened (i.e., converted into 1-dimensional arrays). Only variables at index
* accepted by the specified predicate are considered. For example:
*
*
* {@code
* maximize(SUM, x, t, (i, j, k) -> i < j + k);
* }
*
*
* @param type
* the type of the objective
* @param list
* the involved variables
* @param coeffs
* the coefficients associated with the variables
* @param p
* a predicate allowing us to test if a variable (and its coefficient) at index {@code (i,j,k)} must be
* considered.
* @return an object {@code ObjEntity} that wraps the built objective and allows us to provide note and tags by
* method chaining
*/
default ObjEntity maximize(TypeObjective type, IVar[][][] list, int[][][] coeffs, Intx3Predicate p) {
return maximize(type, select(list, p), selectFromIndexing(coeffs, p));
}
default ObjEntity minimize(TypeObjective type, XNode[] trees) {
control(type.generalizable(), "the specified type must be generalizable");
return imp().minimize(type, trees);
}
default ObjEntity minimize(TypeObjective type, Stream> trees) {
XNode[] atrees = trees.toArray(XNode[]::new);
return minimize(type, atrees);
}
default ObjEntity minimize(TypeObjective type, XNode[] trees, int[] coeffs) {
control(type.generalizable(), "the specified type must be generalizable");
control(trees.length == coeffs.length, "Size of trees and coeffs are different");
return imp().minimize(type, trees, coeffs);
}
default ObjEntity minimize(TypeObjective type, Stream> trees, int[] coeffs) {
XNode[] atrees = trees.toArray(XNode[]::new);
return minimize(type, atrees, coeffs);
}
default ObjEntity maximize(TypeObjective type, XNode[] trees) {
control(type.generalizable(), "the specified type must be generalizable");
return imp().maximize(type, trees);
}
default ObjEntity maximize(TypeObjective type, Stream> trees) {
XNode[] atrees = trees.toArray(XNode[]::new);
return maximize(type, atrees);
}
default ObjEntity maximize(TypeObjective type, XNode[] trees, int[] coeffs) {
control(type.generalizable(), "the specified type must be generalizable");
control(trees.length == coeffs.length, "Size of trees and coeffs are different");
return imp().maximize(type, trees, coeffs);
}
default ObjEntity maximize(TypeObjective type, Stream> trees, int[] coeffs) {
XNode[] atrees = trees.toArray(XNode[]::new);
return maximize(type, atrees, coeffs);
}
/**
* Builds the model. You have to declare variables, constraints and objectives in this method.
*/
void model();
/**
* Called to display a solution given by the specified array. Advanced use: relevant if a solver is plugged. By
* default, it does nothing.
*
* @param values
* the values assigned to the variables
*/
default void prettyDisplay(String[] values) {
}
// ************************************************************************
// ***** Managing Annotations
// ************************************************************************
/**
* Sets the specified variables as those on which a solver should branch in priority. This generates an annotation.
*
* @param list
* a 1-dimensional array of variables
*/
default void decisionVariables(IVar[] list) {
imp().decisionVariables(list);
}
/**
* Sets the specified variables as those on which a solver should branch in priority. This generates an annotation.
*
* @param list
* a 2-dimensional array of variables
*/
default void decisionVariables(IVar[][] list) {
imp().decisionVariables(vars(list));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy