diff --git a/cpmpy/expressions/globalconstraints.py b/cpmpy/expressions/globalconstraints.py index 341fcd3f8..9c6fe3933 100644 --- a/cpmpy/expressions/globalconstraints.py +++ b/cpmpy/expressions/globalconstraints.py @@ -574,7 +574,7 @@ class IncreasingStrict(GlobalConstraint): """ def __init__(self, *args): - super().__init__("increasing_strict", flatlist(args)) + super().__init__("strictly_increasing", flatlist(args)) def decompose(self): """ @@ -597,7 +597,7 @@ class DecreasingStrict(GlobalConstraint): """ def __init__(self, *args): - super().__init__("decreasing_strict", flatlist(args)) + super().__init__("strictly_decreasing", flatlist(args)) def decompose(self): """ diff --git a/cpmpy/solvers/choco.py b/cpmpy/solvers/choco.py index 7976cfe66..d2d502794 100644 --- a/cpmpy/solvers/choco.py +++ b/cpmpy/solvers/choco.py @@ -314,7 +314,8 @@ def transform(self, cpm_expr): cpm_cons = toplevel_list(cpm_expr) supported = {"min", "max", "abs", "count", "element", "alldifferent", "alldifferent_except0", "allequal", "table", "InDomain", "cumulative", "circuit", "gcc", "inverse", "nvalue", "increasing", - "decreasing","increasing_strict","decreasing_strict"} + "decreasing","strictly_increasing","strictly_decreasing"} + # choco supports reification of any constraint, but has a bug in increasing and decreasing supported_reified = {"min", "max", "abs", "count", "element", "alldifferent", "alldifferent_except0", "allequal", "table", "InDomain", "cumulative", "circuit", "gcc", "inverse", "nvalue"} @@ -495,7 +496,7 @@ def _get_constraint(self, cpm_expr): elif isinstance(cpm_expr, GlobalConstraint): # many globals require all variables as arguments - if cpm_expr.name in {"alldifferent", "alldifferent_except0", "allequal", "circuit", "inverse","increasing","decreasing","increasing_strict","decreasing_strict"}: + if cpm_expr.name in {"alldifferent", "alldifferent_except0", "allequal", "circuit", "inverse","increasing","decreasing","strictly_increasing","strictly_decreasing"}: chc_args = self._to_vars(cpm_expr.args) if cpm_expr.name == 'alldifferent': return self.chc_model.all_different(chc_args) @@ -511,9 +512,9 @@ def _get_constraint(self, cpm_expr): return self.chc_model.increasing(chc_args,0) elif cpm_expr.name == "decreasing": return self.chc_model.decreasing(chc_args,0) - elif cpm_expr.name == "increasing_strict": + elif cpm_expr.name == "strictly_increasing": return self.chc_model.increasing(chc_args,1) - elif cpm_expr.name == "decreasing_strict": + elif cpm_expr.name == "strictly_decreasing": return self.chc_model.decreasing(chc_args,1) # but not all diff --git a/cpmpy/solvers/minizinc.py b/cpmpy/solvers/minizinc.py index 55c2d59f2..0bb6bd9fd 100644 --- a/cpmpy/solvers/minizinc.py +++ b/cpmpy/solvers/minizinc.py @@ -418,7 +418,8 @@ def transform(self, cpm_expr): """ cpm_cons = toplevel_list(cpm_expr) supported = {"min", "max", "abs", "element", "count", "nvalue", "alldifferent", "alldifferent_except0", "allequal", - "inverse", "ite" "xor", "table", "cumulative", "circuit", "gcc"} + "inverse", "ite" "xor", "table", "cumulative", "circuit", "gcc", "increasing", + "decreasing","strictly_increasing","strictly_decreasing"} return decompose_in_tree(cpm_cons, supported, supported_reified=supported - {"circuit"}) diff --git a/tests/test_constraints.py b/tests/test_constraints.py index 53a7a2669..062d727ca 100644 --- a/tests/test_constraints.py +++ b/tests/test_constraints.py @@ -14,8 +14,8 @@ EXCLUDE_GLOBAL = {"ortools": {}, "gurobi": {}, "minizinc": {"circuit"}, - "pysat": {"circuit", "element","min","max","count", "nvalue", "allequal","alldifferent","cumulative","increasing","decreasing","increasing_strict","decreasing_strict"}, - "pysdd": {"circuit", "element","min","max","count", "nvalue", "allequal","alldifferent","cumulative","xor","increasing","decreasing","increasing_strict","decreasing_strict"}, + "pysat": {"circuit", "element","min","max","count", "nvalue", "allequal","alldifferent","cumulative","increasing","decreasing","strictly_increasing","strictly_decreasing"}, + "pysdd": {"circuit", "element","min","max","count", "nvalue", "allequal","alldifferent","cumulative","xor","increasing","decreasing","strictly_increasing","strictly_decreasing"}, "exact": {}, "choco": {} } diff --git a/tests/test_globalconstraints.py b/tests/test_globalconstraints.py index e9ae2df66..1f74c80c1 100644 --- a/tests/test_globalconstraints.py +++ b/tests/test_globalconstraints.py @@ -770,6 +770,50 @@ def test_allEqual(self): self.assertTrue(cp.Model([cp.AllEqual(a,b,False, a | b)]).solve()) #self.assertTrue(cp.Model([cp.AllEqual(x,y,b)]).solve()) + def test_increasing(self): + x = cp.intvar(-8, 8) + y = cp.intvar(-7, -1) + b = cp.boolvar() + a = cp.boolvar() + self.assertTrue(cp.Model([cp.Increasing(x,y)]).solve()) + self.assertTrue(cp.Model([cp.Increasing(a,b)]).solve()) + self.assertTrue(cp.Model([cp.Increasing(x,y,b)]).solve()) + z = cp.intvar(2,5) + self.assertFalse(cp.Model([cp.Increasing(z,b)]).solve()) + + def test_decreasing(self): + x = cp.intvar(-8, 8) + y = cp.intvar(-7, -1) + b = cp.boolvar() + a = cp.boolvar() + self.assertTrue(cp.Model([cp.Decreasing(x,y)]).solve()) + self.assertTrue(cp.Model([cp.Decreasing(a,b)]).solve()) + self.assertFalse(cp.Model([cp.Decreasing(x,y,b)]).solve()) + z = cp.intvar(2,5) + self.assertTrue(cp.Model([cp.Decreasing(z,b)]).solve()) + + def test_increasing_strict(self): + x = cp.intvar(-8, 8) + y = cp.intvar(-7, -1) + b = cp.boolvar() + a = cp.boolvar() + self.assertTrue(cp.Model([cp.IncreasingStrict(x,y)]).solve()) + self.assertTrue(cp.Model([cp.IncreasingStrict(a,b)]).solve()) + self.assertTrue(cp.Model([cp.IncreasingStrict(x,y,b)]).solve()) + z = cp.intvar(1,5) + self.assertFalse(cp.Model([cp.IncreasingStrict(z,b)]).solve()) + + def test_decreasing_strict(self): + x = cp.intvar(-8, 8) + y = cp.intvar(-7, 0) + b = cp.boolvar() + a = cp.boolvar() + self.assertTrue(cp.Model([cp.DecreasingStrict(x,y)]).solve()) + self.assertTrue(cp.Model([cp.DecreasingStrict(a,b)]).solve()) + self.assertFalse(cp.Model([cp.DecreasingStrict(x,y,b)]).solve()) + z = cp.intvar(1,5) + self.assertTrue(cp.Model([cp.DecreasingStrict(z,b)]).solve()) + def test_circuit(self): x = cp.intvar(-8, 8) y = cp.intvar(-7, -1)