Skip to content

Unit tests of Increasing and Decreasing - #135

Merged
xcsp3team merged 7 commits into
masterfrom
tests-increasing-decreasing
Sep 29, 2026
Merged

xcsp3team merged 7 commits into
masterfrom
tests-increasing-decreasing

Conversation

@szczepanskiNicolas

@szczepanskiNicolas szczepanskiNicolas commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Unit tests of the constraints Increasing and Decreasing of the section Constraints (Global) of the API (https://pycsp.org/documentation/api/constraints-global/#Increasing and https://pycsp.org/documentation/api/constraints-global/#Decreasing), written as for the previous global constraints (#66, #130), with the same harness.

This PR adds tests (pycsp3/tests/test_constraints_global_increasing_decreasing.py). The bugs found are reported in issues, and the tests concerned are marked as strict expected failures with the numbers of these issues. It also contains the fixes of #136 to #140 (8f8fcba, ad186a2, 289a264, 474d5ff, bb2b86a, one commit per issue), which remove the marks of these issues.

Tests

Increasing() and Decreasing() post an element <ordered> with the operator le, lt, ge or gt (with strict=True for lt and gt); according to XCSP3-core, ordered(X, L, ⊙) holds iff x[i] + l[i] ⊙ x[i+1] for each i. Most tests are run for the four orderings. The tests cover:

  • the forms of the arguments (lists, tuples, generators, slices, nested lists, reversed arrays), sizes, matrices, different domains, negative values, arrays with holes, and the examples of the documentation;
  • the parameter lengths: an integer, a list, a tuple, a range, zero or negative values, as many lengths as terms (the last one being ignored), variables, and integers mixed with variables;
  • expressions (replaced by auxiliary variables), and the option -mini (decomposition into intensional constraints);
  • groups of constraints (rows, sliding windows), and the constraints in logical expressions (~, |, &, imply(), either());
  • terms given several times, the degenerated cases (less than two terms: the constraint always holds), the XCSP3 files generated, and invalid arguments.

Each constraint is solved with ACE, CHOCO and cosoco, and all the solutions are compared with the ones computed by brute force.

File Commit Tests Passed Expected failures (known bugs) Skipped
test_constraints_global_increasing_decreasing.py e912dd0 (tests only, before the fixes) 672 593 67 12
test_constraints_global_increasing_decreasing.py bb2b86a (last commit) 686 653 21 12

Whole suite with the fixes (run locally, master not having moved since the creation of the branch): 3356 passed, 137 skipped and 224 expected failures, no failure. The 46 model files of PyCSP3-models using Increasing() or Decreasing() (58 compilations, with their variants and at most two data files each) give the same results before and after the fixes, except two XCSP3 files where an element <ordered> with a single variable is no longer generated (#138): ProductShelves (toy.json) and Blackhole_z (example.json).

Known bugs

Each issue has the labels bug, unit-tests, Constraints (Global) and the labels of the functions (Increasing, Decreasing).

Issue Solvers (tests) Tests State
#136: Decreasing(strict=True) raises AttributeError in a logical expression (typo Strictly_DECREASING in ConstraintOrdered.to_list()) ACE (6), CHOCO (6), cosoco (6) 18 fixed in 8f8fcba, closed
#137: None is ignored, and lengths of a wrong size are reported by an assert without message without solver 10 fixed in ad186a2, closed
#138: a single term generates an element <ordered> with a single variable (now no constraint; ConstraintDummyConstant.__or__ extended accordingly) without solver 6 fixed in 289a264, closed
#139: lengths mixing integers and variables are accepted, and generate an invalid element <lengths> (now forbidden) without solver 4 fixed in 474d5ff, closed
#140: a term given several times is accepted (now forbidden; on x[0] ⊙ x[0], ACE fails, CHOCO accepts x[0] < x[0], and cosoco reports its own solution as invalid) without solver 8 fixed in bb2b86a, closed
chocoteam/choco-solver#1248 (section 6): ordered with lengths, CHOCO orders the whole sequence x[0], x[0] + l[0], x[1], ..., which loses solutions for some lengths CHOCO (21) 21 open (the only expected failures at the last commit)

Decisions: integers among the terms are refused (TypeError: Wrong type for [x[0], 1, x[1]], accepted by the tests as an explicit error), and as many lengths as terms are tolerated (the last length being ignored).

Cases not handled by the solvers

The constraints on symbolic variables are skipped (ordered on symbolic variables is not part of XCSP3-core; 12 tests).

The functions Increasing() and Decreasing() of the section Constraints
(Global) are tested together (the four orderings: increasing, strictly
increasing, decreasing, strictly decreasing), as the previous global
constraints: forms of the arguments, sizes, matrices, domains, holes, the
examples of the documentation, the parameter lengths (integers, ranges,
tuples, negative values, variables), expressions, the option -mini, groups,
logical contexts, degenerated cases, XCSP3 files and invalid cases, each
constraint being solved with ACE, CHOCO and cosoco and compared with brute
force (semantics of ordered in XCSP3-core: x[i] + l[i] op x[i+1]). The
known bugs are marked as expected failures, to be reported.
…sing and Decreasing

The provisional marks '(to be reported)' now give the issues: #136 to #140 for
PyCSP3, and section 6 of chocoteam/choco-solver#1248 for CHOCO.
Decreasing(strict=True) used in a logical expression (~, |, &, imply(),
either(), If()) raised AttributeError, because of the typo
Strictly_DECREASING in ConstraintOrdered.to_list().

Fixes #136
…reasing()

Increasing(None) and Decreasing(None) were silently ignored, and a number of
lengths different from the number of terms minus 1 (or the number of terms,
the last length being ignored) was reported by an assert without message.
Explicit errors are now reported, as for AllEqual(None).

Fixes #137
…wo terms

With a single term, an element <ordered> with a single variable was generated,
whereas the syntax requires at least two variables. With less than two terms,
_ordered() now returns ConstraintDummyConstant(1), the terms being always
ordered. So that such a constraint can still be used in a logical
expression (Increasing(x[0]) | (x[1] == 1) was accepted before), the operator
| of ConstraintDummyConstant now accepts 1 (true) and an expression as second
operand, which also fixes NotAllEqual(x[0]) | (x[1] == 1).

Fixes #138
…easing()

The lengths mixing integers and variables generated an invalid element
<lengths> (either all integers or all variables, according to XCSP3-core), on
which the parser of ACE and CHOCO fails. An explicit error is now reported.

Fixes #139
A term given several times was accepted; on x[0] op x[0], ACE fails, CHOCO
accepts x[0] < x[0], and cosoco reports its own solution as invalid. An
explicit error is now reported, as for AllDifferent() (#119): the variables
are compared by identity (== being redefined for building expressions), and
the expressions by their textual forms.

Fixes #140
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants