From cfd9deb7261d8a648dda1e14d3a6615a44a33939 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Tue, 26 May 2026 16:23:57 +0200 Subject: [PATCH 01/23] Add test runner tags --- test/test.cpp | 148 ++++++++++++++++++++++++++++++++++++++++++++++++-- test/test.hh | 29 ++++++++++ test/test.hpp | 15 ++++- 3 files changed, 186 insertions(+), 6 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index 09eb2b5d73..4bd26a816e 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -53,12 +53,105 @@ namespace Test { // Log stream std::ostringstream olog; + /// Names of tags supported by the test runner + static const char* tag_names[] = { + "check", + "normal", + "sweep", + nullptr + }; + + /// Masks of tags supported by the test runner + static const unsigned int tag_masks[] = { + TAG_CHECK, + TAG_NORMAL, + TAG_SWEEP + }; + + /// Patterns that reproduce the historic make check selection + static const char* check_patterns[] = { + "Branch::Int::Dense::3", + "FlatZinc::magic_square", + "Int::Arithmetic::Abs", + "Int::Arithmetic::ArgMax", + "Int::Arithmetic::Max::Nary", + "Int::Cumulative::Man::Fix::0::4", + "Int::Distinct::Random", + "Int::Linear::Bool::Int::Lq", + "Int::MiniModel::LinExpr::Bool::352", + "NoGoods::Queens", + "Search::DFS::Sol::Binary::Nary::Binary::1::1::1", + "Set::Dom::Dom::Gr", + "Set::RelOp::ConstSSI::Union", + "Set::Sequence::SeqU1", + "Set::Wait", + nullptr + }; + + /// Patterns for tests that are too heavy for the normal suite + static const char* sweep_patterns[] = { + "FlatZinc::oss", + "FlatZinc::packing", + "FlatZinc::radiation", + "FlatZinc::steiner_triples", + "FlatZinc::template_design", + "FlatZinc::tenpenki", + "FlatZinc::timetabling", + "FlatZinc::trucking", + "Int::Distinct::Pathological", + nullptr + }; + + /// Test whether \a s matches one of \a patterns as a substring + static bool + matches_any_pattern(const std::string& s, const char* patterns[]) { + for (int i=0; patterns[i] != nullptr; i++) + if (s.find(patterns[i]) != std::string::npos) + return true; + return false; + } + + /// Return the tag mask for \a name, or zero if not known + static unsigned int + tag_mask(const char* name) { + for (int i=0; tag_names[i] != nullptr; i++) + if (!strcmp(name, tag_names[i])) + return tag_masks[i]; + if (!strcmp(name, "all")) + return TAG_CHECK | TAG_NORMAL | TAG_SWEEP; + return 0; + } + + /// Print all tag names + static void + print_tags(std::ostream& os) { + for (int i=0; tag_names[i] != nullptr; i++) + os << tag_names[i] << std::endl; + } + + /// Convert \a tags to a comma-separated string + static std::string + tags_to_string(unsigned int tags) { + std::string s; + for (int i=0; tag_names[i] != nullptr; i++) { + if ((tags & tag_masks[i]) != 0) { + if (!s.empty()) + s += ","; + s += tag_names[i]; + } + } + return s; + } + /* * Base class for tests * */ - Base::Base(std::string s) - : _name(std::move(s)), _next(_tests), _rand(Gecode::Support::RandomGenerator()) { + Base::Base(std::string s) + : Base(s, default_tags(s)) {} + + Base::Base(std::string s, unsigned int t) + : _name(std::move(s)), _tags(t), _next(_tests), _rand(Gecode::Support::RandomGenerator()) { _tests = this; _n_tests++; } @@ -92,6 +185,16 @@ namespace Test { Base::~Base() = default; + unsigned int + Base::default_tags(const std::string& s) { + unsigned int tags = TAG_NORMAL; + if (matches_any_pattern(s, sweep_patterns)) + tags = TAG_SWEEP; + if (matches_any_pattern(s, check_patterns)) + tags |= TAG_CHECK; + return tags; + } + Options opt; const int Options::defiter; const unsigned int Options::deffixprob; @@ -135,6 +238,10 @@ namespace Test { << "\t\tprefixing with \"^\" requires a match at the beginning" << std::endl << "\t\tmultiple pattern-options may be given" << std::endl + << "\t-tag (check|normal|sweep|all) default: (none)" << std::endl + << "\t\ttag for the tests to run" << std::endl + << "\t\tmultiple tag-options may be given" + << std::endl << "\t-start (string) default: (none)" << std::endl << "\t\tsimple pattern for the first test to run" << std::endl << "\t-log" @@ -150,6 +257,10 @@ namespace Test { << "\t\tstop on first error or continue" << std::endl << "\t-list" << std::endl << "\t\toutput list of all test cases and exit" << std::endl + << "\t-list-tags" << std::endl + << "\t\toutput list of known test tags and exit" << std::endl + << "\t-list-with-tags" << std::endl + << "\t\toutput list of all test cases with tags and exit" << std::endl ; exit(EXIT_SUCCESS); } else if (!strcmp(argv[i],"-threads")) { @@ -182,6 +293,16 @@ namespace Test { testpat.emplace_back(MT_NOT, argv[i] + 1); else testpat.emplace_back(MT_ANY, argv[i]); + } else if (!strcmp(argv[i],"-tag")) { + if (++i == argc) goto missing; + unsigned int tag = tag_mask(argv[i]); + if (tag == 0) { + std::cerr << "Erroneous argument (-tag)" << std::endl + << " unknown tag: " << argv[i] << std::endl; + exit(EXIT_FAILURE); + } + testtags |= tag; + use_testtags = true; } else if (!strcmp(argv[i],"-start")) { if (++i == argc) goto missing; start_from = argv[i]; @@ -196,6 +317,10 @@ namespace Test { } } else if (!strcmp(argv[i],"-list")) { list = true; + } else if (!strcmp(argv[i],"-list-tags")) { + list_tags = true; + } else if (!strcmp(argv[i],"-list-with-tags")) { + list_with_tags = true; } i++; } @@ -264,6 +389,10 @@ namespace Test { } } + bool Options::is_test_tags_matching(unsigned int tags) const { + return !use_testtags || ((tags & testtags) != 0); + } + /// Run a single test, returning true iff the test succeeded bool run_test(Base* test, unsigned int test_seed, const Options& options, std::ostream& ostream) { unsigned int seed = options.replay ? options.seed : test_seed; @@ -499,7 +628,8 @@ namespace Test { continue; } } - if (options.is_test_name_matching(t->name())) { + if (options.is_test_name_matching(t->name()) && + options.is_test_tags_matching(t->tags())) { tests.emplace_back(t); } } @@ -510,11 +640,19 @@ namespace Test { opt = Options(); opt.parse(argc, argv); + if (opt.list_tags) { + print_tags(std::cout); + return EXIT_SUCCESS; + } + Base::sort(); - if (opt.list) { + if (opt.list || opt.list_with_tags) { for (Base* t = Base::tests(); t != nullptr; t = t->next()) { - std::cout << t->name() << std::endl; + std::cout << t->name(); + if (opt.list_with_tags) + std::cout << " [" << tags_to_string(t->tags()) << "]"; + std::cout << std::endl; } return EXIT_SUCCESS; } diff --git a/test/test.hh b/test/test.hh index 99f772f3f5..8014f21ef0 100755 --- a/test/test.hh +++ b/test/test.hh @@ -94,6 +94,13 @@ namespace Test { MT_FIRST //< Positive match at beginning }; + /// Tags for test selection + enum TestTag { + TAG_CHECK = 1U << 0, ///< Basic integrity tests + TAG_NORMAL = 1U << 1, ///< Normal test suite + TAG_SWEEP = 1U << 2 ///< Really heavy sweep tests + }; + /// Commandline options class GECODE_TEST_EXPORT Options { public: @@ -117,10 +124,18 @@ namespace Test { bool log; /// Patterns to test against std::vector > testpat; + /// Tags to test against + unsigned int testtags; + /// Whether test tags have been requested + bool use_testtags; /// Name of first test to start with const char* start_from; /// Whether to list all tests bool list; + /// Whether to list known tags + bool list_tags; + /// Whether to include tags when listing tests + bool list_with_tags; /// Initialize options with defaults Options(void); @@ -134,6 +149,8 @@ namespace Test { * patterns; with no patterns, every test name matches. */ bool is_test_name_matching(const std::string& test_name) const; + /// True iff test tags should be executed according to the requested tags. With no tag request, always true. + bool is_test_tags_matching(unsigned int tags) const; }; /// The options @@ -144,6 +161,8 @@ namespace Test { private: /// Name of the test std::string _name; + /// Tags assigned to the test + unsigned int _tags; /// Next test Base* _next; /// All tests @@ -153,10 +172,20 @@ namespace Test { public: /// Create and register test with name \a s Base(std::string s); + /// Create and register test with name \a s and tags \a t + Base(std::string s, unsigned int t); /// Sort tests alphabetically static void sort(void); /// Return name of test const std::string& name(void) const; + /// Return tags for test + unsigned int tags(void) const; + /// Add tags \a t to test + void add_tags(unsigned int t); + /// Remove tags \a t from test + void remove_tags(unsigned int t); + /// Return default tags for test named \a s + static unsigned int default_tags(const std::string& s); /// Return all tests static Base* tests(void); /// Return next test diff --git a/test/test.hpp b/test/test.hpp index 5c3f45e2d7..ed41969909 100755 --- a/test/test.hpp +++ b/test/test.hpp @@ -40,7 +40,8 @@ namespace Test { inline Options::Options(void) : threads(1), seed(0), replay(false), iter(defiter), fixprob(deffixprob), - stop(true), log(false), testpat(), start_from(nullptr), list(false) + stop(true), log(false), testpat(), testtags(0), use_testtags(false), + start_from(nullptr), list(false), list_tags(false), list_with_tags(false) {} /* @@ -51,6 +52,18 @@ namespace Test { Base::name(void) const { return _name; } + inline unsigned int + Base::tags(void) const { + return _tags; + } + inline void + Base::add_tags(unsigned int t) { + _tags |= t; + } + inline void + Base::remove_tags(unsigned int t) { + _tags &= ~t; + } inline Base* Base::tests(void) { return _tests; From c4740271154ed55b75f631a54c83080a94ce5059 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Tue, 26 May 2026 16:24:01 +0200 Subject: [PATCH 02/23] Use test tags for check targets --- CMakeLists.txt | 95 +++++++++++--------------------------------------- Makefile.in | 62 +++++--------------------------- 2 files changed, 30 insertions(+), 127 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f80173aff..40ba86ba80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1493,68 +1493,7 @@ if(BUILD_TESTING) "${GECODE_TEST_BLACKBOX_LOG}.dll_parallel") endif() - set(GECODE_CHECK_TESTS - Branch::Int::Dense::3 - Int::Arithmetic::Abs - Int::Arithmetic::ArgMax - Int::Arithmetic::Max::Nary - Int::Cumulative::Man::Fix::0::4 - Int::Distinct::Random - Int::Extensional::Reg::Sparse::NFAPrefix - Int::Extensional::Reg::Sparse::RandomNFADifferential - Int::Extensional::TupleSet::Sparse::IncrementalDelta - Int::Extensional::TupleSet::Auto::DefaultDispatch - Int::Linear::Bool::Int::Lq - Int::MiniModel::LinExpr::Bool::352 - NoGoods::Queens - Search::PBS::ConstructionFailure - Search::WorkerControl:: - Search::DFS::Sol::Binary::Nary::Binary::1::1::1) - if(GECODE_ENABLE_FLATZINC) - list(INSERT GECODE_CHECK_TESTS 1 - FlatZinc::Options - FlatZinc::magic_square - FlatZinc::blackbox) - endif() - if(GECODE_ENABLE_SET_VARS) - list(APPEND GECODE_CHECK_TESTS - Set::Dom::Dom::Gr - Set::RelOp::ConstSSI::Union - Set::Sequence::SeqU1 - Set::Wait) - endif() - if(GECODE_ENABLE_FLOAT_VARS) - set(GECODE_FLOAT_CHECK_TESTS - Float::Arithmetic::PositiveNRootBounds - Float::Arithmetic::PowConsistency - Float::Arithmetic::MultZeroEndpoint - Float::Arithmetic::Pow::N::2::XY::Sol::C - Float::Arithmetic::NRoot::N::2::XY::Sol::C - Float::Arithmetic::Mult::XYZ::Sol::C) - list(APPEND GECODE_CHECK_TESTS ${GECODE_FLOAT_CHECK_TESTS}) - - # Keep the fast CI selection honest when Float regressions are added or - # the list above is edited. These names must remain registered in the - # ordinary check target rather than living only in ad-hoc test commands. - set(GECODE_REQUIRED_FLOAT_CHECK_TESTS - Float::Arithmetic::PositiveNRootBounds - Float::Arithmetic::PowConsistency - Float::Arithmetic::MultZeroEndpoint - Float::Arithmetic::Pow::N::2::XY::Sol::C - Float::Arithmetic::NRoot::N::2::XY::Sol::C - Float::Arithmetic::Mult::XYZ::Sol::C) - foreach(gecode_required_float_test ${GECODE_REQUIRED_FLOAT_CHECK_TESTS}) - if(NOT gecode_required_float_test IN_LIST GECODE_CHECK_TESTS) - message(FATAL_ERROR - "Required Float check test is missing: ${gecode_required_float_test}") - endif() - endforeach() - endif() - - set(GECODE_CHECK_ARGS -iter 2 -threads 0 -fixprob 1) - foreach(gecode_check_test ${GECODE_CHECK_TESTS}) - list(APPEND GECODE_CHECK_ARGS -test ${gecode_check_test}) - endforeach() + set(GECODE_CHECK_ARGS -iter 2 -threads 0 -tag check) # Keep ctest robust while leaving the large test binaries out of the default build. set(GECODE_TEST_BUILD_TARGETS gecode-test) @@ -1570,27 +1509,19 @@ if(BUILD_TESTING) FIXTURES_SETUP "${GECODE_TEST_BUILD_FIXTURES}" RESOURCE_LOCK gecode-test-build) add_test(NAME test COMMAND gecode-test ${GECODE_CHECK_ARGS}) - set_tests_properties(test PROPERTIES + add_test(NAME test-normal COMMAND gecode-test -tag normal) + add_test(NAME test-sweep COMMAND gecode-test -tag sweep) + set_tests_properties(test test-normal test-sweep PROPERTIES FIXTURES_REQUIRED gecode-test-built) if(GECODE_ENABLE_FLATZINC) set(GECODE_TEST_BLACKBOX_ENV "GECODE_TEST_BLACKBOX_EXEC=$" "GECODE_TEST_BLACKBOX_DLL=$" "GECODE_TEST_BLACKBOX_LOG=${GECODE_TEST_BLACKBOX_LOG}") - set_tests_properties(test PROPERTIES + set_tests_properties(test test-normal test-sweep PROPERTIES ENVIRONMENT "${GECODE_TEST_BLACKBOX_ENV}") endif() set(GECODE_CHECK_DEPENDS gecode-test) - if(GECODE_ENABLE_FLOAT_VARS) - add_custom_target(verify-gecode-check-tests - COMMAND ${CMAKE_COMMAND} - "-DTEST_EXECUTABLE=$" - "-DREQUIRED_TESTS=${GECODE_REQUIRED_FLOAT_CHECK_TESTS}" - -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/VerifyTestSelection.cmake - DEPENDS gecode-test - VERBATIM) - list(APPEND GECODE_CHECK_DEPENDS verify-gecode-check-tests) - endif() if(GECODE_ENABLE_FLATZINC) list(APPEND GECODE_CHECK_DEPENDS gecode-test-blackbox-exec @@ -1609,6 +1540,14 @@ if(BUILD_TESTING) DEPENDS ${GECODE_CHECK_DEPENDS} USES_TERMINAL) endif() + add_custom_target(check-normal + COMMAND $ -tag normal + DEPENDS gecode-test + USES_TERMINAL) + add_custom_target(check-sweep + COMMAND $ -tag sweep + DEPENDS gecode-test + USES_TERMINAL) if(GECODE_ENABLE_FAULT_INJECTION) set(GECODE_FAULT_CHECK_ARGS -iter 1 -threads 1 -test "^Fault::") add_test(NAME fault COMMAND gecode-fault-test ${GECODE_FAULT_CHECK_ARGS}) @@ -1625,10 +1564,18 @@ if(BUILD_TESTING) message(WARNING "Skipping gecode-test/check targets because required modules are disabled") add_custom_target(check COMMAND ${CMAKE_COMMAND} -E echo "Skipping check target because required modules are disabled") + add_custom_target(check-normal + COMMAND ${CMAKE_COMMAND} -E echo "Skipping check-normal target because required modules are disabled") + add_custom_target(check-sweep + COMMAND ${CMAKE_COMMAND} -E echo "Skipping check-sweep target because required modules are disabled") endif() else() add_custom_target(check COMMAND ${CMAKE_COMMAND} -E echo "Skipping check target because BUILD_TESTING is OFF") + add_custom_target(check-normal + COMMAND ${CMAKE_COMMAND} -E echo "Skipping check-normal target because BUILD_TESTING is OFF") + add_custom_target(check-sweep + COMMAND ${CMAKE_COMMAND} -E echo "Skipping check-sweep target because BUILD_TESTING is OFF") endif() # --------------------------------------------------------------------------- diff --git a/Makefile.in b/Makefile.in index adc245839e..0b0fcc6be6 100755 --- a/Makefile.in +++ b/Makefile.in @@ -1503,72 +1503,28 @@ compileexamples: $(EXAMPLEEXE) test: mkcompiledirs $(BLACKBOXFIXTURES) @$(MAKE) $(VARIMP) $(TESTEXE) $(TESTPUBLICSMOKEEXES) -CHECKTESTS = Branch::Int::Dense::3 \ - Int::Arithmetic::Abs \ - Int::Arithmetic::ArgMax \ - Int::Arithmetic::Max::Nary \ - Int::Cumulative::Man::Fix::0::4 \ - Int::Distinct::Random \ - Int::Extensional::Reg::Sparse::NFAPrefix \ - Int::Extensional::Reg::Sparse::RandomNFADifferential \ - Int::Extensional::TupleSet::Sparse::IncrementalDelta \ - Int::Extensional::TupleSet::Auto::DefaultDispatch \ - Int::Linear::Bool::Int::Lq \ - Int::MiniModel::LinExpr::Bool::352 \ - NoGoods::Queens \ - Search::PBS::ConstructionFailure \ - Search::WorkerControl:: \ - Search::DFS::Sol::Binary::Nary::Binary::1::1::1 - -ifeq "@enable_set_vars@" "yes" -CHECKTESTS += \ - Set::Dom::Dom::Gr \ - Set::RelOp::ConstSSI::Union \ - Set::Sequence::SeqU1 \ - Set::Wait -endif - ifeq "@enable_flatzinc@" "yes" -CHECKTESTS += FlatZinc::magic_square FlatZinc::Options FlatZinc::blackbox BLACKBOXCHECKENV = \ GECODE_TEST_BLACKBOX_EXEC=$(abspath $(BLACKBOXEXEC)) \ GECODE_TEST_BLACKBOX_DLL=$(abspath $(BLACKBOXDLL)) \ GECODE_TEST_BLACKBOX_LOG=$(BLACKBOXLOG) endif -ifeq "@enable_float_vars@" "yes" -FLOATCHECKTESTS = Float::Arithmetic::PositiveNRootBounds \ - Float::Arithmetic::PowConsistency \ - Float::Arithmetic::MultZeroEndpoint \ - Float::Arithmetic::Pow::N::2::XY::Sol::C \ - Float::Arithmetic::NRoot::N::2::XY::Sol::C \ - Float::Arithmetic::Mult::XYZ::Sol::C -CHECKTESTS += $(FLOATCHECKTESTS) -REQUIREDFLOATCHECKTESTS = Float::Arithmetic::PositiveNRootBounds \ - Float::Arithmetic::PowConsistency \ - Float::Arithmetic::MultZeroEndpoint \ - Float::Arithmetic::Pow::N::2::XY::Sol::C \ - Float::Arithmetic::NRoot::N::2::XY::Sol::C \ - Float::Arithmetic::Mult::XYZ::Sol::C -endif - # A basic integrity test check: test @for t in $(TESTPUBLICSMOKEEXES); do \ $(RUNENVIRONMENT) $$t || exit 1; \ done - @for t in $(REQUIREDFLOATCHECKTESTS); do \ - case " $(CHECKTESTS) " in *" $$t "*) ;; \ - *) echo "Required Float check test is missing: $$t" >&2; exit 1 ;; \ - esac; \ - if ! $(RUNENVIRONMENT) $(TESTEXE) -list | grep -Fqx "$$t"; then \ - echo "Required Float check test is not registered: $$t" >&2; \ - exit 1; \ - fi; \ - done $(BLACKBOXCHECKENV) $(RUNENVIRONMENT) \ - $(TESTEXE) -iter 2 -threads 0 -fixprob 1 \ - $(CHECKTESTS:%=-test %) + $(TESTEXE) -iter 2 -threads 0 -tag check + +# The normal test suite without sweep tests +check-normal: test + $(BLACKBOXCHECKENV) $(RUNENVIRONMENT) $(TESTEXE) -tag normal + +# Really heavy sweep tests +check-sweep: test + $(BLACKBOXCHECKENV) $(RUNENVIRONMENT) $(TESTEXE) -tag sweep .PHONY: regenerate regenerate: From e71b0a8563909e8673f7de6ff3e26d8380acf858 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Tue, 26 May 2026 16:29:11 +0200 Subject: [PATCH 03/23] Use scoped enum for test tags --- test/test.cpp | 44 ++++++++++++++++++++++---------------------- test/test.hh | 48 ++++++++++++++++++++++++++++++++++++------------ test/test.hpp | 48 ++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 100 insertions(+), 40 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index 4bd26a816e..706f36e594 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -62,10 +62,10 @@ namespace Test { }; /// Masks of tags supported by the test runner - static const unsigned int tag_masks[] = { - TAG_CHECK, - TAG_NORMAL, - TAG_SWEEP + static const TestTag tag_values[] = { + TestTag::check, + TestTag::normal, + TestTag::sweep }; /// Patterns that reproduce the historic make check selection @@ -111,15 +111,15 @@ namespace Test { return false; } - /// Return the tag mask for \a name, or zero if not known - static unsigned int - tag_mask(const char* name) { + /// Return the tag set for \a name, or an empty set if not known + static TestTags + tag_set(const char* name) { for (int i=0; tag_names[i] != nullptr; i++) if (!strcmp(name, tag_names[i])) - return tag_masks[i]; + return TestTags(tag_values[i]); if (!strcmp(name, "all")) - return TAG_CHECK | TAG_NORMAL | TAG_SWEEP; - return 0; + return TestTags::all(); + return TestTags(); } /// Print all tag names @@ -131,10 +131,10 @@ namespace Test { /// Convert \a tags to a comma-separated string static std::string - tags_to_string(unsigned int tags) { + tags_to_string(TestTags tags) { std::string s; for (int i=0; tag_names[i] != nullptr; i++) { - if ((tags & tag_masks[i]) != 0) { + if (tags.overlaps(TestTags(tag_values[i]))) { if (!s.empty()) s += ","; s += tag_names[i]; @@ -150,7 +150,7 @@ namespace Test { Base::Base(std::string s) : Base(s, default_tags(s)) {} - Base::Base(std::string s, unsigned int t) + Base::Base(std::string s, TestTags t) : _name(std::move(s)), _tags(t), _next(_tests), _rand(Gecode::Support::RandomGenerator()) { _tests = this; _n_tests++; } @@ -185,13 +185,13 @@ namespace Test { Base::~Base() = default; - unsigned int + TestTags Base::default_tags(const std::string& s) { - unsigned int tags = TAG_NORMAL; + TestTags tags(TestTag::normal); if (matches_any_pattern(s, sweep_patterns)) - tags = TAG_SWEEP; + tags = TestTags(TestTag::sweep); if (matches_any_pattern(s, check_patterns)) - tags |= TAG_CHECK; + tags.add(TestTag::check); return tags; } @@ -295,13 +295,13 @@ namespace Test { testpat.emplace_back(MT_ANY, argv[i]); } else if (!strcmp(argv[i],"-tag")) { if (++i == argc) goto missing; - unsigned int tag = tag_mask(argv[i]); - if (tag == 0) { + TestTags tag = tag_set(argv[i]); + if (tag.empty()) { std::cerr << "Erroneous argument (-tag)" << std::endl << " unknown tag: " << argv[i] << std::endl; exit(EXIT_FAILURE); } - testtags |= tag; + testtags.add(tag); use_testtags = true; } else if (!strcmp(argv[i],"-start")) { if (++i == argc) goto missing; @@ -389,8 +389,8 @@ namespace Test { } } - bool Options::is_test_tags_matching(unsigned int tags) const { - return !use_testtags || ((tags & testtags) != 0); + bool Options::is_test_tags_matching(TestTags tags) const { + return !use_testtags || tags.overlaps(testtags); } /// Run a single test, returning true iff the test succeeded diff --git a/test/test.hh b/test/test.hh index 8014f21ef0..05b2702bfa 100755 --- a/test/test.hh +++ b/test/test.hh @@ -95,10 +95,34 @@ namespace Test { }; /// Tags for test selection - enum TestTag { - TAG_CHECK = 1U << 0, ///< Basic integrity tests - TAG_NORMAL = 1U << 1, ///< Normal test suite - TAG_SWEEP = 1U << 2 ///< Really heavy sweep tests + enum class TestTag : unsigned int { + check = 1U << 0, ///< Basic integrity tests + normal = 1U << 1, ///< Normal test suite + sweep = 1U << 2 ///< Really heavy sweep tests + }; + + /// Set of test tags + class TestTags { + private: + /// Bit mask for tags + unsigned int _mask; + /// Initialize from raw bit mask \a m + explicit TestTags(unsigned int m); + public: + /// Initialize with no tags + TestTags(void); + /// Initialize with tag \a t + TestTags(TestTag t); + /// Return set with all known tags + static TestTags all(void); + /// Whether no tags are set + bool empty(void) const; + /// Whether this set contains any tag from \a t + bool overlaps(TestTags t) const; + /// Add tags \a t + void add(TestTags t); + /// Remove tags \a t + void remove(TestTags t); }; /// Commandline options @@ -125,7 +149,7 @@ namespace Test { /// Patterns to test against std::vector > testpat; /// Tags to test against - unsigned int testtags; + TestTags testtags; /// Whether test tags have been requested bool use_testtags; /// Name of first test to start with @@ -150,7 +174,7 @@ namespace Test { */ bool is_test_name_matching(const std::string& test_name) const; /// True iff test tags should be executed according to the requested tags. With no tag request, always true. - bool is_test_tags_matching(unsigned int tags) const; + bool is_test_tags_matching(TestTags tags) const; }; /// The options @@ -162,7 +186,7 @@ namespace Test { /// Name of the test std::string _name; /// Tags assigned to the test - unsigned int _tags; + TestTags _tags; /// Next test Base* _next; /// All tests @@ -173,19 +197,19 @@ namespace Test { /// Create and register test with name \a s Base(std::string s); /// Create and register test with name \a s and tags \a t - Base(std::string s, unsigned int t); + Base(std::string s, TestTags t); /// Sort tests alphabetically static void sort(void); /// Return name of test const std::string& name(void) const; /// Return tags for test - unsigned int tags(void) const; + TestTags tags(void) const; /// Add tags \a t to test - void add_tags(unsigned int t); + void add_tags(TestTags t); /// Remove tags \a t from test - void remove_tags(unsigned int t); + void remove_tags(TestTags t); /// Return default tags for test named \a s - static unsigned int default_tags(const std::string& s); + static TestTags default_tags(const std::string& s); /// Return all tests static Base* tests(void); /// Return next test diff --git a/test/test.hpp b/test/test.hpp index ed41969909..0167521039 100755 --- a/test/test.hpp +++ b/test/test.hpp @@ -33,6 +33,42 @@ namespace Test { + /* + * Test tags + * + */ + inline + TestTags::TestTags(unsigned int m) + : _mask(m) {} + inline + TestTags::TestTags(void) + : _mask(0) {} + inline + TestTags::TestTags(TestTag t) + : _mask(static_cast(t)) {} + inline TestTags + TestTags::all(void) { + return TestTags(static_cast(TestTag::check) | + static_cast(TestTag::normal) | + static_cast(TestTag::sweep)); + } + inline bool + TestTags::empty(void) const { + return _mask == 0; + } + inline bool + TestTags::overlaps(TestTags t) const { + return (_mask & t._mask) != 0; + } + inline void + TestTags::add(TestTags t) { + _mask |= t._mask; + } + inline void + TestTags::remove(TestTags t) { + _mask &= ~t._mask; + } + /* * Commandline options * @@ -40,7 +76,7 @@ namespace Test { inline Options::Options(void) : threads(1), seed(0), replay(false), iter(defiter), fixprob(deffixprob), - stop(true), log(false), testpat(), testtags(0), use_testtags(false), + stop(true), log(false), testpat(), testtags(), use_testtags(false), start_from(nullptr), list(false), list_tags(false), list_with_tags(false) {} @@ -52,17 +88,17 @@ namespace Test { Base::name(void) const { return _name; } - inline unsigned int + inline TestTags Base::tags(void) const { return _tags; } inline void - Base::add_tags(unsigned int t) { - _tags |= t; + Base::add_tags(TestTags t) { + _tags.add(t); } inline void - Base::remove_tags(unsigned int t) { - _tags &= ~t; + Base::remove_tags(TestTags t) { + _tags.remove(t); } inline Base* Base::tests(void) { From cd51164ad7af59439e9aa422810ad3e766502fc8 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Tue, 26 May 2026 17:00:22 +0200 Subject: [PATCH 04/23] Document tag-based test targets --- CMakeLists.txt | 6 ++---- docs/cmake-build.md | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 40ba86ba80..e3ba7f4f93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1509,16 +1509,14 @@ if(BUILD_TESTING) FIXTURES_SETUP "${GECODE_TEST_BUILD_FIXTURES}" RESOURCE_LOCK gecode-test-build) add_test(NAME test COMMAND gecode-test ${GECODE_CHECK_ARGS}) - add_test(NAME test-normal COMMAND gecode-test -tag normal) - add_test(NAME test-sweep COMMAND gecode-test -tag sweep) - set_tests_properties(test test-normal test-sweep PROPERTIES + set_tests_properties(test PROPERTIES FIXTURES_REQUIRED gecode-test-built) if(GECODE_ENABLE_FLATZINC) set(GECODE_TEST_BLACKBOX_ENV "GECODE_TEST_BLACKBOX_EXEC=$" "GECODE_TEST_BLACKBOX_DLL=$" "GECODE_TEST_BLACKBOX_LOG=${GECODE_TEST_BLACKBOX_LOG}") - set_tests_properties(test test-normal test-sweep PROPERTIES + set_tests_properties(test PROPERTIES ENVIRONMENT "${GECODE_TEST_BLACKBOX_ENV}") endif() set(GECODE_CHECK_DEPENDS gecode-test) diff --git a/docs/cmake-build.md b/docs/cmake-build.md index c4ce8a172b..5c699ac089 100644 --- a/docs/cmake-build.md +++ b/docs/cmake-build.md @@ -72,6 +72,37 @@ cmake --install build/vs2022-vcpkg --config Release --prefix C:/path/to/install Visual Studio is a multi-config generator, so use `--config Release` (or `Debug`) for build/install/check commands rather than `CMAKE_BUILD_TYPE`. +## Test Targets + +When `BUILD_TESTING=ON`, CMake builds the `gecode-test` test runner on demand. +The standard `check` target runs the basic integrity suite: + +```bash +cmake --build build --target check +``` + +Two additional targets expose broader tag-based suites: + +```bash +cmake --build build --target check-normal +cmake --build build --target check-sweep +``` + +`check-normal` runs the normal test suite. `check-sweep` runs tests tagged as +heavy sweep tests and is intended for deliberate, longer-running validation. + +The test runner can also be invoked directly with tags: + +```bash +gecode-test -tag check +gecode-test -tag normal +gecode-test -tag sweep +gecode-test -tag normal -tag sweep +``` + +Use `gecode-test -list-tags` to list known tags and +`gecode-test -list-with-tags` to inspect test assignments. + ## Build Conventions and Key Options ### Common CMake options From 2a0c350d85ac63f03a83174d5ef8ff845c92458e Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Sun, 6 Sep 2026 11:51:59 +0200 Subject: [PATCH 05/23] Preserve check coverage with test tags --- CMakeLists.txt | 18 +++++++++++++----- Makefile.in | 2 +- test/test.cpp | 10 ++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3ba7f4f93..a17c499541 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1493,7 +1493,7 @@ if(BUILD_TESTING) "${GECODE_TEST_BLACKBOX_LOG}.dll_parallel") endif() - set(GECODE_CHECK_ARGS -iter 2 -threads 0 -tag check) + set(GECODE_CHECK_ARGS -iter 2 -threads 0 -fixprob 1 -tag check) # Keep ctest robust while leaving the large test binaries out of the default build. set(GECODE_TEST_BUILD_TARGETS gecode-test) @@ -1532,16 +1532,24 @@ if(BUILD_TESTING) $ ${GECODE_CHECK_ARGS} DEPENDS ${GECODE_CHECK_DEPENDS} USES_TERMINAL) + add_custom_target(check-normal + COMMAND ${CMAKE_COMMAND} -E env + GECODE_TEST_BLACKBOX_EXEC=$ + GECODE_TEST_BLACKBOX_DLL=$ + GECODE_TEST_BLACKBOX_LOG=${GECODE_TEST_BLACKBOX_LOG} + $ -tag normal + DEPENDS ${GECODE_CHECK_DEPENDS} + USES_TERMINAL) else() add_custom_target(check COMMAND $ ${GECODE_CHECK_ARGS} DEPENDS ${GECODE_CHECK_DEPENDS} USES_TERMINAL) + add_custom_target(check-normal + COMMAND $ -tag normal + DEPENDS gecode-test + USES_TERMINAL) endif() - add_custom_target(check-normal - COMMAND $ -tag normal - DEPENDS gecode-test - USES_TERMINAL) add_custom_target(check-sweep COMMAND $ -tag sweep DEPENDS gecode-test diff --git a/Makefile.in b/Makefile.in index 0b0fcc6be6..2d595117d0 100755 --- a/Makefile.in +++ b/Makefile.in @@ -1516,7 +1516,7 @@ check: test $(RUNENVIRONMENT) $$t || exit 1; \ done $(BLACKBOXCHECKENV) $(RUNENVIRONMENT) \ - $(TESTEXE) -iter 2 -threads 0 -tag check + $(TESTEXE) -iter 2 -threads 0 -fixprob 1 -tag check # The normal test suite without sweep tests check-normal: test diff --git a/test/test.cpp b/test/test.cpp index 706f36e594..cd0b2f9f00 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -71,12 +71,22 @@ namespace Test { /// Patterns that reproduce the historic make check selection static const char* check_patterns[] = { "Branch::Int::Dense::3", + "FlatZinc::Options", "FlatZinc::magic_square", + "FlatZinc::blackbox", + "Float::Arithmetic::PositiveNRootBounds", + "Float::Arithmetic::PowConsistency", + "Float::Arithmetic::MultZeroEndpoint", + "Float::Arithmetic::Pow::N::2::XY::Sol::C", + "Float::Arithmetic::NRoot::N::2::XY::Sol::C", + "Float::Arithmetic::Mult::XYZ::Sol::C", "Int::Arithmetic::Abs", "Int::Arithmetic::ArgMax", "Int::Arithmetic::Max::Nary", "Int::Cumulative::Man::Fix::0::4", "Int::Distinct::Random", + "Int::Extensional::TupleSet::Sparse::IncrementalDelta", + "Int::Extensional::TupleSet::Auto::DefaultDispatch", "Int::Linear::Bool::Int::Lq", "Int::MiniModel::LinExpr::Bool::352", "NoGoods::Queens", From a2f5fb6bcd868b92b0e4217acf99fc32fa370118 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Sun, 6 Sep 2026 12:28:02 +0200 Subject: [PATCH 06/23] Keep exhaustive test families out of normal runs --- test/test.cpp | 94 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 2 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index cd0b2f9f00..d55acf3a13 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -98,6 +98,58 @@ namespace Test { nullptr }; + /// Representative cases retained from otherwise exhaustive sweep families + static const char* normal_patterns[] = { + "Float::Arithmetic::Abs::XX::A", + "Float::Arithmetic::Div::A", + "Float::Arithmetic::Max::Bin::XXX::A", + "Float::Arithmetic::Min::Bin::XXX::A", + "Float::Arithmetic::Sqr::XX::A", + "Float::Arithmetic::Sqrt::XX::A", + "Float::Linear::Float::Eq::11::0::1", + "Float::Linear::Var::Eq::11::1", + "Float::MiniModel::LinExpr::000", + "Float::Transcendental::Exp::XX::A", + "Float::Transcendental::Log::XX::A", + "Float::Transcendental::Pow::N::1.5::XX::A", + "Float::Trigonometric::ACos::XX::A", + "Float::Trigonometric::ASin::XX::A", + "Float::Trigonometric::ATan::XX::A", + "Float::Trigonometric::Cos::XX::A", + "Float::Trigonometric::Sin::XX::A", + "Float::Trigonometric::Tan::XX::A", + "Int::Arithmetic::Nroot::XX::1::Bnd::A", + "Int::Arithmetic::Pow::XX::0::Bnd::A", + "Int::Channel::Bool::Multi::A", + "Int::Circuit::Cost::Dom::4::0", + "Int::Count::Distinct::Bnd::Dense", + "Int::Cumulative::Opt::Fix::-2147483646::-1", + "Int::Cumulative::Opt::Flex::-2147483646::4::0::2", + "Int::Distinct::Bnd::Dense", + "Int::Distinct::Dom::Dense", + "Int::Distinct::Offset::Dense::Bnd", + "Int::GCC::Int::All::Max::Bnd", + "Int::Linear::Int::Int::Eq::Bnd::11::0::1", + "Int::MiniModel::SetExpr::Const::000::0::0", + "Int::MiniModel::SetExpr::Expr::000::000::0", + "Int::NValues::Int::Int::Eq::1::0", + "Int::NoOverlap::Int::2::2::[1,1,1,1]::[1,1,1,1]", + "Int::Path::Cost::Dom::3::0", + "Int::Rel::Int::Array::Eq::0::4", + "Int::Unary::Man::Fix::-2147483646::[2,2,0,2,2]::Def+A", + "Int::Unary::Man::Flex::-2147483646::4::0::2::Def+A", + "Int::Unary::Opt::Fix::-2147483646::[2,2,0,2,2]::Def+A", + "Int::Unary::Opt::Flex::-2147483646::4::0::2::Def+A", + "Search::BAB::Sol::BalGr::Binary::Binary::Binary::1::1::1", + "Set::Branch::Dense::3", + "Set::Channel::Bool::1", + "Set::Element::Disjoint", + "Set::Precede::Multi::[1,2,3]", + "Set::Rel::Bin::Cmpl::S0", + "Set::RelOp::ConstISI::DUnion::Cmpl::0::0", + nullptr + }; + /// Patterns for tests that are too heavy for the normal suite static const char* sweep_patterns[] = { "FlatZinc::oss", @@ -108,7 +160,43 @@ namespace Test { "FlatZinc::tenpenki", "FlatZinc::timetabling", "FlatZinc::trucking", + "Float::Arithmetic", + "Float::Linear::Float", + "Float::Linear::Var", + "Float::MiniModel::LinExpr", + "Float::Transcendental", + "Float::Trigonometric", + "Int::Arithmetic::Nroot", + "Int::Arithmetic::Pow", + "Int::Channel", + "Int::Circuit", + "Int::Count::Distinct", + "Int::Cumulative::Man", + "Int::Cumulative::Opt", + "Int::Distinct::Bnd", + "Int::Distinct::Dom", + "Int::Distinct::Offset", "Int::Distinct::Pathological", + "Int::Extensional::TupleSet", + "Int::GCC", + "Int::Linear::Bool", + "Int::Linear::Int", + "Int::MiniModel::LinExpr", + "Int::MiniModel::SetExpr", + "Int::NValues::Int", + "Int::NoOverlap", + "Int::Path", + "Int::Rel::Int", + "Int::Unary", + "Search::BAB::Sol", + "Search::DFS::Sol", + "Set::Branch", + "Set::Channel", + "Set::Dom", + "Set::Element", + "Set::Precede", + "Set::Rel", + "Set::RelOp", nullptr }; @@ -197,10 +285,12 @@ namespace Test { TestTags Base::default_tags(const std::string& s) { + const bool check = matches_any_pattern(s, check_patterns); + const bool normal = matches_any_pattern(s, normal_patterns); TestTags tags(TestTag::normal); - if (matches_any_pattern(s, sweep_patterns)) + if (!check && !normal && matches_any_pattern(s, sweep_patterns)) tags = TestTags(TestTag::sweep); - if (matches_any_pattern(s, check_patterns)) + if (check) tags.add(TestTag::check); return tags; } From 1463ccefc7d1072a980d7b5fd01156384ee06ccb Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Sun, 6 Sep 2026 13:10:23 +0200 Subject: [PATCH 07/23] Integrate test tags with public harness --- CMakeLists.txt | 23 +++- Makefile.in | 4 +- cmake/GecodeSources.cmake | 5 +- test/gecode-tags.cpp | 204 ++++++++++++++++++++++++++++++++++ test/gecode-tags.hh | 46 ++++++++ test/public-runner-smoke.cpp | 61 +++++++++- test/test-main.cpp | 4 +- test/test.cpp | 209 +++++++---------------------------- test/test.hh | 4 +- test/test.hpp | 6 - 10 files changed, 369 insertions(+), 197 deletions(-) create mode 100644 test/gecode-tags.cpp create mode 100644 test/gecode-tags.hh diff --git a/CMakeLists.txt b/CMakeLists.txt index a17c499541..f5172cae61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -814,7 +814,10 @@ ${CONFIG_OUT}") include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GecodeSources.cmake) if(GECODE_ENABLE_FAULT_INJECTION) list(APPEND GECODE_SUPPORT_SOURCES gecode/support/failpoint.cpp) - set(GECODE_FAULT_TEST_SOURCES ${GECODE_TEST_MAIN_SOURCE} test/fault.cpp) + set(GECODE_FAULT_TEST_SOURCES + test/test-main.cpp + test/gecode-tags.cpp + test/fault.cpp) endif() # --------------------------------------------------------------------------- @@ -1461,7 +1464,7 @@ if(BUILD_TESTING) endif() if(GECODE_CAN_BUILD_TESTS) - add_executable(gecode-test EXCLUDE_FROM_ALL ${GECODE_TEST_MAIN_SOURCE} ${GECODE_TEST_SOURCES_SELECTED}) + add_executable(gecode-test EXCLUDE_FROM_ALL ${GECODE_TEST_MAIN_SOURCES} ${GECODE_TEST_SOURCES_SELECTED}) set(GECODE_TEST_LINK_LIBS gecodeminimodel) if(TARGET gecodetestset) list(APPEND GECODE_TEST_LINK_LIBS gecodetestset) @@ -1540,6 +1543,14 @@ if(BUILD_TESTING) $ -tag normal DEPENDS ${GECODE_CHECK_DEPENDS} USES_TERMINAL) + add_custom_target(check-sweep + COMMAND ${CMAKE_COMMAND} -E env + GECODE_TEST_BLACKBOX_EXEC=$ + GECODE_TEST_BLACKBOX_DLL=$ + GECODE_TEST_BLACKBOX_LOG=${GECODE_TEST_BLACKBOX_LOG} + $ -tag sweep + DEPENDS ${GECODE_CHECK_DEPENDS} + USES_TERMINAL) else() add_custom_target(check COMMAND $ ${GECODE_CHECK_ARGS} @@ -1549,11 +1560,11 @@ if(BUILD_TESTING) COMMAND $ -tag normal DEPENDS gecode-test USES_TERMINAL) + add_custom_target(check-sweep + COMMAND $ -tag sweep + DEPENDS gecode-test + USES_TERMINAL) endif() - add_custom_target(check-sweep - COMMAND $ -tag sweep - DEPENDS gecode-test - USES_TERMINAL) if(GECODE_ENABLE_FAULT_INJECTION) set(GECODE_FAULT_CHECK_ARGS -iter 1 -threads 1 -test "^Fault::") add_test(NAME fault COMMAND gecode-fault-test ${GECODE_FAULT_CHECK_ARGS}) diff --git a/Makefile.in b/Makefile.in index 2d595117d0..af3aed80bb 100755 --- a/Makefile.in +++ b/Makefile.in @@ -1281,7 +1281,7 @@ BLACKBOXSRC = $(BLACKBOXEXECSRC) $(BLACKBOXDLLSRC) TESTCORESRC = test/test.cpp TESTCOREOBJ = $(TESTCORESRC:%.cpp=%$(OBJSUFFIX)) -TESTMAINSRC = test/test-main.cpp +TESTMAINSRC = test/test-main.cpp test/gecode-tags.cpp TESTMAINOBJ = $(TESTMAINSRC:%.cpp=%$(OBJSUFFIX)) TESTINTSEAMSRC = test/int.cpp TESTINTSEAMOBJ = $(TESTINTSEAMSRC:%.cpp=%$(OBJSUFFIX)) @@ -1311,7 +1311,7 @@ TESTSRC = \ $(ARRAYTESTSRC0) $(FLATZINCTESTSRC0) $(BLACKBOXSRC) TESTHDR0 = \ - test.hh test.hpp int.hh int.hpp set.hh set.hpp float.hh float.hpp \ + test.hh test.hpp gecode-tags.hh int.hh int.hpp set.hh set.hpp float.hh float.hpp \ branch.hh assign.hh flatzinc.hh TESTHDR = $(TESTHDR0:%=test/%) diff --git a/cmake/GecodeSources.cmake b/cmake/GecodeSources.cmake index eb013c2682..12bfbae9fb 100644 --- a/cmake/GecodeSources.cmake +++ b/cmake/GecodeSources.cmake @@ -261,7 +261,10 @@ set(GECODE_TEST_FLOAT_SOURCES test/float.cpp ) -set(GECODE_TEST_MAIN_SOURCE test/test-main.cpp) +set(GECODE_TEST_MAIN_SOURCES + test/test-main.cpp + test/gecode-tags.cpp +) set(GECODE_TEST_PUBLIC_RUNNER_SMOKE_SOURCE test/public-runner-smoke.cpp) set(GECODE_TEST_PUBLIC_INT_SMOKE_SOURCE test/public-int-smoke.cpp) set(GECODE_TEST_PUBLIC_SET_SMOKE_SOURCE test/public-set-smoke.cpp) diff --git a/test/gecode-tags.cpp b/test/gecode-tags.cpp new file mode 100644 index 0000000000..5513ceb21d --- /dev/null +++ b/test/gecode-tags.cpp @@ -0,0 +1,204 @@ +/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ +/* + * Main authors: + * Christian Schulte + * + * Contributing authors: + * Mikael Lagerkvist + * + * Copyright: + * Christian Schulte, 2026 + * + * This file is part of Gecode, the generic constraint + * development environment: + * http://www.gecode.org + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "test/test.hh" +#include "test/gecode-tags.hh" + +#include + +namespace Test { + + /// Patterns that reproduce the historic make check selection + static const char* const check_patterns[] = { + "Branch::Int::Dense::3", + "FlatZinc::Options", + "FlatZinc::magic_square", + "FlatZinc::blackbox", + "Float::Arithmetic::PositiveNRootBounds", + "Float::Arithmetic::PowConsistency", + "Float::Arithmetic::MultZeroEndpoint", + "Float::Arithmetic::Pow::N::2::XY::Sol::C", + "Float::Arithmetic::NRoot::N::2::XY::Sol::C", + "Float::Arithmetic::Mult::XYZ::Sol::C", + "Int::Arithmetic::Abs", + "Int::Arithmetic::ArgMax", + "Int::Arithmetic::Max::Nary", + "Int::Cumulative::Man::Fix::0::4", + "Int::Distinct::Random", + "Int::Extensional::TupleSet::Sparse::IncrementalDelta", + "Int::Extensional::TupleSet::Auto::DefaultDispatch", + "Int::Linear::Bool::Int::Lq", + "Int::MiniModel::LinExpr::Bool::352", + "NoGoods::Queens", + "Search::DFS::Sol::Binary::Nary::Binary::1::1::1", + "Set::Dom::Dom::Gr", + "Set::RelOp::ConstSSI::Union", + "Set::Sequence::SeqU1", + "Set::Wait", + nullptr + }; + + /// Representative cases retained from otherwise exhaustive sweep families + static const char* const normal_patterns[] = { + "Float::Arithmetic::Abs::XX::A", + "Float::Arithmetic::Div::A", + "Float::Arithmetic::Max::Bin::XXX::A", + "Float::Arithmetic::Min::Bin::XXX::A", + "Float::Arithmetic::Sqr::XX::A", + "Float::Arithmetic::Sqrt::XX::A", + "Float::Linear::Float::Eq::11::0::1", + "Float::Linear::Var::Eq::11::1", + "Float::MiniModel::LinExpr::000", + "Float::Transcendental::Exp::XX::A", + "Float::Transcendental::Log::XX::A", + "Float::Transcendental::Pow::N::1.5::XX::A", + "Float::Trigonometric::ACos::XX::A", + "Float::Trigonometric::ASin::XX::A", + "Float::Trigonometric::ATan::XX::A", + "Float::Trigonometric::Cos::XX::A", + "Float::Trigonometric::Sin::XX::A", + "Float::Trigonometric::Tan::XX::A", + "Int::Arithmetic::Nroot::XX::1::Bnd::A", + "Int::Arithmetic::Pow::XX::0::Bnd::A", + "Int::Channel::Bool::Multi::A", + "Int::Circuit::Cost::Dom::4::0", + "Int::Count::Distinct::Bnd::Dense", + "Int::Cumulative::Opt::Fix::-2147483646::-1", + "Int::Cumulative::Opt::Flex::-2147483646::4::0::2", + "Int::Distinct::Bnd::Dense", + "Int::Distinct::Dom::Dense", + "Int::Distinct::Offset::Dense::Bnd", + "Int::GCC::Int::All::Max::Bnd", + "Int::Linear::Int::Int::Eq::Bnd::11::0::1", + "Int::MiniModel::SetExpr::Const::000::0::0", + "Int::MiniModel::SetExpr::Expr::000::000::0", + "Int::NValues::Int::Int::Eq::1::0", + "Int::NoOverlap::Int::2::2::[1,1,1,1]::[1,1,1,1]", + "Int::Path::Cost::Dom::3::0", + "Int::Rel::Int::Array::Eq::0::4", + "Int::Unary::Man::Fix::-2147483646::[2,2,0,2,2]::Def+A", + "Int::Unary::Man::Flex::-2147483646::4::0::2::Def+A", + "Int::Unary::Opt::Fix::-2147483646::[2,2,0,2,2]::Def+A", + "Int::Unary::Opt::Flex::-2147483646::4::0::2::Def+A", + "Search::BAB::Sol::BalGr::Binary::Binary::Binary::1::1::1", + "Set::Branch::Dense::3", + "Set::Channel::Bool::1", + "Set::Element::Disjoint", + "Set::Precede::Multi::[1,2,3]", + "Set::Rel::Bin::Cmpl::S0", + "Set::RelOp::ConstISI::DUnion::Cmpl::0::0", + nullptr + }; + + /// Patterns for tests that are too heavy for the normal suite + static const char* const sweep_patterns[] = { + "FlatZinc::oss", + "FlatZinc::packing", + "FlatZinc::radiation", + "FlatZinc::steiner_triples", + "FlatZinc::template_design", + "FlatZinc::tenpenki", + "FlatZinc::timetabling", + "FlatZinc::trucking", + "Float::Arithmetic", + "Float::Linear::Float", + "Float::Linear::Var", + "Float::MiniModel::LinExpr", + "Float::Transcendental", + "Float::Trigonometric", + "Int::Arithmetic::Nroot", + "Int::Arithmetic::Pow", + "Int::Channel", + "Int::Circuit", + "Int::Count::Distinct", + "Int::Cumulative::Man", + "Int::Cumulative::Opt", + "Int::Distinct::Bnd", + "Int::Distinct::Dom", + "Int::Distinct::Offset", + "Int::Distinct::Pathological", + "Int::Extensional::TupleSet", + "Int::GCC", + "Int::Linear::Bool", + "Int::Linear::Int", + "Int::MiniModel::LinExpr", + "Int::MiniModel::SetExpr", + "Int::NValues::Int", + "Int::NoOverlap", + "Int::Path", + "Int::Rel::Int", + "Int::Unary", + "Search::BAB::Sol", + "Search::DFS::Sol", + "Set::Branch", + "Set::Channel", + "Set::Dom", + "Set::Element", + "Set::Precede", + "Set::Rel", + "Set::RelOp", + nullptr + }; + + static bool + matches_any_pattern(const std::string& name, + const char* const patterns[]) { + for (int i=0; patterns[i] != nullptr; i++) + if (name.find(patterns[i]) != std::string::npos) + return true; + return false; + } + + void + apply_gecode_test_tags(void) { + for (Base* test = Base::tests(); test != nullptr; + test = test->next()) { + const std::string& name = test->name(); + const bool check = matches_any_pattern(name, check_patterns); + const bool representative = matches_any_pattern(name, normal_patterns); + if (!check && !representative && + matches_any_pattern(name, sweep_patterns)) { + test->remove_tags(TestTag::normal); + test->add_tags(TestTag::sweep); + } + if (check) + test->add_tags(TestTag::check); + } + } + +} + +// STATISTICS: test-core diff --git a/test/gecode-tags.hh b/test/gecode-tags.hh new file mode 100644 index 0000000000..aea4e19c93 --- /dev/null +++ b/test/gecode-tags.hh @@ -0,0 +1,46 @@ +/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ +/* + * Main authors: + * Mikael Lagerkvist + * + * Copyright: + * Mikael Lagerkvist, 2026 + * + * This file is part of Gecode, the generic constraint + * development environment: + * http://www.gecode.org + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef GECODE_TEST_GECODE_TAGS_HH +#define GECODE_TEST_GECODE_TAGS_HH + +namespace Test { + + /// Apply Gecode's suite classification to its registered tests + void apply_gecode_test_tags(void); + +} + +#endif + +// STATISTICS: test-core diff --git a/test/public-runner-smoke.cpp b/test/public-runner-smoke.cpp index 5f1b5d764d..3550668a6e 100644 --- a/test/public-runner-smoke.cpp +++ b/test/public-runner-smoke.cpp @@ -48,7 +48,7 @@ namespace { class PassingSmokeTest : public Test::Base { public: PassingSmokeTest(void) - : Test::Base("Smoke::A-Pass") {} + : Test::Base("Int::Linear::Int::Smoke::A-Pass") {} bool run(void) override { passing_runs++; @@ -59,7 +59,7 @@ namespace { class FailingSmokeTest : public Test::Base { public: FailingSmokeTest(void) - : Test::Base("Smoke::B-Fail") {} + : Test::Base("Smoke::B-Fail", Test::TestTag::sweep) {} bool run(void) override { failing_runs++; @@ -117,7 +117,7 @@ main(void) { "-list should succeed")) { return EXIT_FAILURE; } - const std::string pass_name = "Smoke::A-Pass"; + const std::string pass_name = "Int::Linear::Int::Smoke::A-Pass"; const std::string fail_name = "Smoke::B-Fail"; const std::size_t pass_pos = list_output.find(pass_name); const std::size_t fail_pos = list_output.find(fail_name); @@ -135,8 +135,40 @@ main(void) { return EXIT_FAILURE; } + std::string tagged_list_output; + if (!require(run_and_capture({"public-runner-smoke", "-list-with-tags"}, + tagged_list_output) == EXIT_SUCCESS, + "-list-with-tags should succeed")) { + return EXIT_FAILURE; + } + if (!require(tagged_list_output.find(pass_name + " [normal]") != std::string::npos, + "default test should have the normal tag")) { + return EXIT_FAILURE; + } + if (!require(tagged_list_output.find("Smoke::B-Fail [sweep]") != std::string::npos, + "explicit test tag should be listed")) { + return EXIT_FAILURE; + } + + std::string normal_output; + if (!require(run_and_capture({"public-runner-smoke", "-tag", "normal", + "-iter", "1", "-stop", "true"}, + normal_output) == EXIT_SUCCESS, + "normal tag selection should succeed")) { + return EXIT_FAILURE; + } + if (!require(normal_output.find(pass_name) != std::string::npos && + normal_output.find(fail_name) == std::string::npos, + "normal tag selection chose the wrong tests")) { + return EXIT_FAILURE; + } + if (!require(passing_runs == 1 && failing_runs == 0, + "normal tag selection run counts are wrong")) { + return EXIT_FAILURE; + } + std::string pass_output; - if (!require(run_and_capture({"public-runner-smoke", "-test", "Smoke::A-Pass", "-iter", "1", "-stop", "true"}, + if (!require(run_and_capture({"public-runner-smoke", "-test", "Int::Linear::Int::Smoke::A-Pass", "-iter", "1", "-stop", "true"}, pass_output) == EXIT_SUCCESS, "filtered passing run should succeed")) { return EXIT_FAILURE; @@ -153,7 +185,7 @@ main(void) { "filtered passing run did not report success")) { return EXIT_FAILURE; } - if (!require(passing_runs == 1 && failing_runs == 0, + if (!require(passing_runs == 2 && failing_runs == 0, "filtered passing run counts are wrong")) { return EXIT_FAILURE; } @@ -176,7 +208,7 @@ main(void) { "filtered failing run did not preserve test diagnostics")) { return EXIT_FAILURE; } - if (!require(passing_runs == 1 && failing_runs == 1, + if (!require(passing_runs == 2 && failing_runs == 1, "filtered failing run counts are wrong")) { return EXIT_FAILURE; } @@ -197,6 +229,23 @@ main(void) { "replay should restore the reported random state")) return EXIT_FAILURE; + std::string combined_output; + if (!require(run_and_capture({"public-runner-smoke", "-tag", "normal", + "-tag", "sweep", "-iter", "1", "-stop", "true"}, + combined_output) == EXIT_FAILURE, + "multiple tags should select their union")) { + return EXIT_FAILURE; + } + if (!require(combined_output.find(pass_name) != std::string::npos && + combined_output.find(fail_name) != std::string::npos, + "multiple tag selection did not run both tags")) { + return EXIT_FAILURE; + } + if (!require(passing_runs == 3 && failing_runs == 2, + "multiple tag selection run counts are wrong")) { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } diff --git a/test/test-main.cpp b/test/test-main.cpp index 745ed1bc73..bd760b7a5d 100644 --- a/test/test-main.cpp +++ b/test/test-main.cpp @@ -1,4 +1,4 @@ -/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ +/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Main authors: * Christian Schulte @@ -34,6 +34,7 @@ */ #include "test/test.hh" +#include "test/gecode-tags.hh" #ifdef GECODE_HAS_MTRACE #include @@ -44,6 +45,7 @@ main(int argc, char* argv[]) { #ifdef GECODE_HAS_MTRACE mtrace(); #endif + Test::apply_gecode_test_tags(); return Test::run_registered_tests(argc, argv); } diff --git a/test/test.cpp b/test/test.cpp index d55acf3a13..cefdf41797 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -53,168 +53,33 @@ namespace Test { // Log stream std::ostringstream olog; - /// Names of tags supported by the test runner - static const char* tag_names[] = { - "check", - "normal", - "sweep", - nullptr + /// A command-line name and its corresponding test tag + struct TestTagDescription { + const char* name; + TestTag tag; }; - /// Masks of tags supported by the test runner - static const TestTag tag_values[] = { - TestTag::check, - TestTag::normal, - TestTag::sweep + /// Tags supported by the test runner + static const TestTagDescription test_tag_descriptions[] = { + {"check", TestTag::check}, + {"normal", TestTag::normal}, + {"sweep", TestTag::sweep} }; - /// Patterns that reproduce the historic make check selection - static const char* check_patterns[] = { - "Branch::Int::Dense::3", - "FlatZinc::Options", - "FlatZinc::magic_square", - "FlatZinc::blackbox", - "Float::Arithmetic::PositiveNRootBounds", - "Float::Arithmetic::PowConsistency", - "Float::Arithmetic::MultZeroEndpoint", - "Float::Arithmetic::Pow::N::2::XY::Sol::C", - "Float::Arithmetic::NRoot::N::2::XY::Sol::C", - "Float::Arithmetic::Mult::XYZ::Sol::C", - "Int::Arithmetic::Abs", - "Int::Arithmetic::ArgMax", - "Int::Arithmetic::Max::Nary", - "Int::Cumulative::Man::Fix::0::4", - "Int::Distinct::Random", - "Int::Extensional::TupleSet::Sparse::IncrementalDelta", - "Int::Extensional::TupleSet::Auto::DefaultDispatch", - "Int::Linear::Bool::Int::Lq", - "Int::MiniModel::LinExpr::Bool::352", - "NoGoods::Queens", - "Search::DFS::Sol::Binary::Nary::Binary::1::1::1", - "Set::Dom::Dom::Gr", - "Set::RelOp::ConstSSI::Union", - "Set::Sequence::SeqU1", - "Set::Wait", - nullptr - }; - - /// Representative cases retained from otherwise exhaustive sweep families - static const char* normal_patterns[] = { - "Float::Arithmetic::Abs::XX::A", - "Float::Arithmetic::Div::A", - "Float::Arithmetic::Max::Bin::XXX::A", - "Float::Arithmetic::Min::Bin::XXX::A", - "Float::Arithmetic::Sqr::XX::A", - "Float::Arithmetic::Sqrt::XX::A", - "Float::Linear::Float::Eq::11::0::1", - "Float::Linear::Var::Eq::11::1", - "Float::MiniModel::LinExpr::000", - "Float::Transcendental::Exp::XX::A", - "Float::Transcendental::Log::XX::A", - "Float::Transcendental::Pow::N::1.5::XX::A", - "Float::Trigonometric::ACos::XX::A", - "Float::Trigonometric::ASin::XX::A", - "Float::Trigonometric::ATan::XX::A", - "Float::Trigonometric::Cos::XX::A", - "Float::Trigonometric::Sin::XX::A", - "Float::Trigonometric::Tan::XX::A", - "Int::Arithmetic::Nroot::XX::1::Bnd::A", - "Int::Arithmetic::Pow::XX::0::Bnd::A", - "Int::Channel::Bool::Multi::A", - "Int::Circuit::Cost::Dom::4::0", - "Int::Count::Distinct::Bnd::Dense", - "Int::Cumulative::Opt::Fix::-2147483646::-1", - "Int::Cumulative::Opt::Flex::-2147483646::4::0::2", - "Int::Distinct::Bnd::Dense", - "Int::Distinct::Dom::Dense", - "Int::Distinct::Offset::Dense::Bnd", - "Int::GCC::Int::All::Max::Bnd", - "Int::Linear::Int::Int::Eq::Bnd::11::0::1", - "Int::MiniModel::SetExpr::Const::000::0::0", - "Int::MiniModel::SetExpr::Expr::000::000::0", - "Int::NValues::Int::Int::Eq::1::0", - "Int::NoOverlap::Int::2::2::[1,1,1,1]::[1,1,1,1]", - "Int::Path::Cost::Dom::3::0", - "Int::Rel::Int::Array::Eq::0::4", - "Int::Unary::Man::Fix::-2147483646::[2,2,0,2,2]::Def+A", - "Int::Unary::Man::Flex::-2147483646::4::0::2::Def+A", - "Int::Unary::Opt::Fix::-2147483646::[2,2,0,2,2]::Def+A", - "Int::Unary::Opt::Flex::-2147483646::4::0::2::Def+A", - "Search::BAB::Sol::BalGr::Binary::Binary::Binary::1::1::1", - "Set::Branch::Dense::3", - "Set::Channel::Bool::1", - "Set::Element::Disjoint", - "Set::Precede::Multi::[1,2,3]", - "Set::Rel::Bin::Cmpl::S0", - "Set::RelOp::ConstISI::DUnion::Cmpl::0::0", - nullptr - }; - - /// Patterns for tests that are too heavy for the normal suite - static const char* sweep_patterns[] = { - "FlatZinc::oss", - "FlatZinc::packing", - "FlatZinc::radiation", - "FlatZinc::steiner_triples", - "FlatZinc::template_design", - "FlatZinc::tenpenki", - "FlatZinc::timetabling", - "FlatZinc::trucking", - "Float::Arithmetic", - "Float::Linear::Float", - "Float::Linear::Var", - "Float::MiniModel::LinExpr", - "Float::Transcendental", - "Float::Trigonometric", - "Int::Arithmetic::Nroot", - "Int::Arithmetic::Pow", - "Int::Channel", - "Int::Circuit", - "Int::Count::Distinct", - "Int::Cumulative::Man", - "Int::Cumulative::Opt", - "Int::Distinct::Bnd", - "Int::Distinct::Dom", - "Int::Distinct::Offset", - "Int::Distinct::Pathological", - "Int::Extensional::TupleSet", - "Int::GCC", - "Int::Linear::Bool", - "Int::Linear::Int", - "Int::MiniModel::LinExpr", - "Int::MiniModel::SetExpr", - "Int::NValues::Int", - "Int::NoOverlap", - "Int::Path", - "Int::Rel::Int", - "Int::Unary", - "Search::BAB::Sol", - "Search::DFS::Sol", - "Set::Branch", - "Set::Channel", - "Set::Dom", - "Set::Element", - "Set::Precede", - "Set::Rel", - "Set::RelOp", - nullptr - }; - - /// Test whether \a s matches one of \a patterns as a substring - static bool - matches_any_pattern(const std::string& s, const char* patterns[]) { - for (int i=0; patterns[i] != nullptr; i++) - if (s.find(patterns[i]) != std::string::npos) - return true; - return false; + TestTags + TestTags::all(void) { + TestTags tags; + for (const TestTagDescription& description : test_tag_descriptions) + tags.add(description.tag); + return tags; } /// Return the tag set for \a name, or an empty set if not known static TestTags tag_set(const char* name) { - for (int i=0; tag_names[i] != nullptr; i++) - if (!strcmp(name, tag_names[i])) - return TestTags(tag_values[i]); + for (const TestTagDescription& description : test_tag_descriptions) + if (!strcmp(name, description.name)) + return TestTags(description.tag); if (!strcmp(name, "all")) return TestTags::all(); return TestTags(); @@ -223,19 +88,31 @@ namespace Test { /// Print all tag names static void print_tags(std::ostream& os) { - for (int i=0; tag_names[i] != nullptr; i++) - os << tag_names[i] << std::endl; + for (const TestTagDescription& description : test_tag_descriptions) + os << description.name << std::endl; + } + + /// Convert the known tag names to a command-line choice list + static std::string + tag_choices(void) { + std::string choices; + for (const TestTagDescription& description : test_tag_descriptions) { + if (!choices.empty()) + choices += "|"; + choices += description.name; + } + return choices + "|all"; } /// Convert \a tags to a comma-separated string static std::string tags_to_string(TestTags tags) { std::string s; - for (int i=0; tag_names[i] != nullptr; i++) { - if (tags.overlaps(TestTags(tag_values[i]))) { + for (const TestTagDescription& description : test_tag_descriptions) { + if (tags.overlaps(TestTags(description.tag))) { if (!s.empty()) s += ","; - s += tag_names[i]; + s += description.name; } } return s; @@ -246,7 +123,7 @@ namespace Test { * */ Base::Base(std::string s) - : Base(s, default_tags(s)) {} + : Base(s, TestTag::normal) {} Base::Base(std::string s, TestTags t) : _name(std::move(s)), _tags(t), _next(_tests), _rand(Gecode::Support::RandomGenerator()) { @@ -283,18 +160,6 @@ namespace Test { Base::~Base() = default; - TestTags - Base::default_tags(const std::string& s) { - const bool check = matches_any_pattern(s, check_patterns); - const bool normal = matches_any_pattern(s, normal_patterns); - TestTags tags(TestTag::normal); - if (!check && !normal && matches_any_pattern(s, sweep_patterns)) - tags = TestTags(TestTag::sweep); - if (check) - tags.add(TestTag::check); - return tags; - } - Options opt; const int Options::defiter; const unsigned int Options::deffixprob; @@ -338,7 +203,7 @@ namespace Test { << "\t\tprefixing with \"^\" requires a match at the beginning" << std::endl << "\t\tmultiple pattern-options may be given" << std::endl - << "\t-tag (check|normal|sweep|all) default: (none)" << std::endl + << "\t-tag (" << tag_choices() << ") default: (none)" << std::endl << "\t\ttag for the tests to run" << std::endl << "\t\tmultiple tag-options may be given" << std::endl diff --git a/test/test.hh b/test/test.hh index 05b2702bfa..33ad7375b4 100755 --- a/test/test.hh +++ b/test/test.hh @@ -194,7 +194,7 @@ namespace Test { /// How many tests static unsigned int _n_tests; public: - /// Create and register test with name \a s + /// Create and register a normal test with name \a s Base(std::string s); /// Create and register test with name \a s and tags \a t Base(std::string s, TestTags t); @@ -208,8 +208,6 @@ namespace Test { void add_tags(TestTags t); /// Remove tags \a t from test void remove_tags(TestTags t); - /// Return default tags for test named \a s - static TestTags default_tags(const std::string& s); /// Return all tests static Base* tests(void); /// Return next test diff --git a/test/test.hpp b/test/test.hpp index 0167521039..3ea1b9a6b1 100755 --- a/test/test.hpp +++ b/test/test.hpp @@ -46,12 +46,6 @@ namespace Test { inline TestTags::TestTags(TestTag t) : _mask(static_cast(t)) {} - inline TestTags - TestTags::all(void) { - return TestTags(static_cast(TestTag::check) | - static_cast(TestTag::normal) | - static_cast(TestTag::sweep)); - } inline bool TestTags::empty(void) const { return _mask == 0; From 3e5c09dcfd69c53552cd4e92c816e9d71ddcee45 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Sun, 6 Sep 2026 14:37:47 +0200 Subject: [PATCH 08/23] Declare test tags with test definitions --- CMakeLists.txt | 1 - Makefile.in | 4 +- cmake/GecodeSources.cmake | 1 - test/branch/set.cpp | 4 +- test/flatzinc.cpp | 25 +++- test/flatzinc.hh | 12 ++ test/flatzinc/blackbox.cpp | 42 +++--- test/flatzinc/magicsq_3.cpp | 2 +- test/flatzinc/magicsq_4.cpp | 2 +- test/flatzinc/magicsq_5.cpp | 2 +- test/flatzinc/oss.cpp | 2 +- test/flatzinc/packing.cpp | 2 +- test/flatzinc/radiation.cpp | 2 +- test/flatzinc/steiner_triples.cpp | 2 +- test/flatzinc/template_design.cpp | 2 +- test/flatzinc/tenpenki_1.cpp | 2 +- test/flatzinc/tenpenki_2.cpp | 2 +- test/flatzinc/tenpenki_3.cpp | 2 +- test/flatzinc/tenpenki_4.cpp | 2 +- test/flatzinc/tenpenki_5.cpp | 2 +- test/flatzinc/tenpenki_6.cpp | 2 +- test/flatzinc/timetabling.cpp | 2 +- test/flatzinc/trucking.cpp | 2 +- test/float.hh | 8 ++ test/float.hpp | 33 +++-- test/float/arithmetic.cpp | 107 ++++++++++------ test/float/linear.cpp | 8 +- test/float/mm-lin.cpp | 3 +- test/float/transcendental.cpp | 29 +++-- test/float/trigonometric.cpp | 42 +++--- test/gecode-tags.cpp | 204 ------------------------------ test/gecode-tags.hh | 46 ------- test/int.hh | 16 +++ test/int.hpp | 40 ++++-- test/int/arithmetic.cpp | 40 ++++-- test/int/channel.cpp | 12 +- test/int/circuit.cpp | 14 +- test/int/cumulative.cpp | 17 ++- test/int/distinct.cpp | 18 ++- test/int/extensional.cpp | 62 +++++---- test/int/gcc.cpp | 13 +- test/int/linear.cpp | 15 ++- test/int/mm-lin.cpp | 11 +- test/int/no-overlap.cpp | 14 +- test/int/nvalues.cpp | 8 +- test/int/rel.cpp | 18 +-- test/int/unary.cpp | 22 +++- test/nogoods.cpp | 5 +- test/search.cpp | 22 +++- test/set.hh | 6 +- test/set/channel.cpp | 10 +- test/set/dom.cpp | 18 ++- test/set/element.cpp | 16 +-- test/set/exec.cpp | 4 +- test/set/mm-set.cpp | 8 +- test/set/precede.cpp | 6 +- test/set/rel-op-const.cpp | 17 ++- test/set/rel-op.cpp | 6 +- test/set/rel.cpp | 4 +- test/set/sequence.cpp | 5 +- test/test-main.cpp | 2 - test/test.hh | 4 + test/test.hpp | 8 ++ 63 files changed, 548 insertions(+), 514 deletions(-) delete mode 100644 test/gecode-tags.cpp delete mode 100644 test/gecode-tags.hh diff --git a/CMakeLists.txt b/CMakeLists.txt index f5172cae61..ec012b79d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -816,7 +816,6 @@ if(GECODE_ENABLE_FAULT_INJECTION) list(APPEND GECODE_SUPPORT_SOURCES gecode/support/failpoint.cpp) set(GECODE_FAULT_TEST_SOURCES test/test-main.cpp - test/gecode-tags.cpp test/fault.cpp) endif() diff --git a/Makefile.in b/Makefile.in index af3aed80bb..2d595117d0 100755 --- a/Makefile.in +++ b/Makefile.in @@ -1281,7 +1281,7 @@ BLACKBOXSRC = $(BLACKBOXEXECSRC) $(BLACKBOXDLLSRC) TESTCORESRC = test/test.cpp TESTCOREOBJ = $(TESTCORESRC:%.cpp=%$(OBJSUFFIX)) -TESTMAINSRC = test/test-main.cpp test/gecode-tags.cpp +TESTMAINSRC = test/test-main.cpp TESTMAINOBJ = $(TESTMAINSRC:%.cpp=%$(OBJSUFFIX)) TESTINTSEAMSRC = test/int.cpp TESTINTSEAMOBJ = $(TESTINTSEAMSRC:%.cpp=%$(OBJSUFFIX)) @@ -1311,7 +1311,7 @@ TESTSRC = \ $(ARRAYTESTSRC0) $(FLATZINCTESTSRC0) $(BLACKBOXSRC) TESTHDR0 = \ - test.hh test.hpp gecode-tags.hh int.hh int.hpp set.hh set.hpp float.hh float.hpp \ + test.hh test.hpp int.hh int.hpp set.hh set.hpp float.hh float.hpp \ branch.hh assign.hh flatzinc.hh TESTHDR = $(TESTHDR0:%=test/%) diff --git a/cmake/GecodeSources.cmake b/cmake/GecodeSources.cmake index 12bfbae9fb..9201998b3b 100644 --- a/cmake/GecodeSources.cmake +++ b/cmake/GecodeSources.cmake @@ -263,7 +263,6 @@ set(GECODE_TEST_FLOAT_SOURCES set(GECODE_TEST_MAIN_SOURCES test/test-main.cpp - test/gecode-tags.cpp ) set(GECODE_TEST_PUBLIC_RUNNER_SMOKE_SOURCE test/public-runner-smoke.cpp) set(GECODE_TEST_PUBLIC_INT_SMOKE_SOURCE test/public-int-smoke.cpp) diff --git a/test/branch/set.cpp b/test/branch/set.cpp index 2ec3d914bb..401a6e6c68 100644 --- a/test/branch/set.cpp +++ b/test/branch/set.cpp @@ -42,7 +42,9 @@ namespace Test { namespace Branch { public: /// Create and register test Set(const std::string& s, const Gecode::IntSet& d, int n) - : SetTest(s,n,d) {} + : SetTest(s,n,d) { + tags(s == "Dense::3" ? TestTag::normal : TestTag::sweep); + } /// Post propagators on variables \a x virtual void post(Gecode::Space& home, Gecode::SetVarArray& x) { Gecode::SetVarArgs xx(x.size()-1); diff --git a/test/flatzinc.cpp b/test/flatzinc.cpp index b7c1873b0b..5417997651 100755 --- a/test/flatzinc.cpp +++ b/test/flatzinc.cpp @@ -81,7 +81,9 @@ namespace Test { namespace FlatZinc { } public: GistStatisticsMode(void) - : Base("FlatZinc::Options::GistStatisticsMode") {} + : Base("FlatZinc::Options::GistStatisticsMode") { + add_tags(TestTag::check); + } virtual bool run(void) { return @@ -96,6 +98,7 @@ namespace Test { namespace FlatZinc { #ifndef GECODE_HAS_GIST /// Verify that unavailable Gist mode is rejected instead of running search. FlatZincErrorTest gist_unavailable( + TestTags(TestTag::normal,TestTag::check), "Options::GistUnavailable", "var 1..1: x :: output_var;\nsolve satisfy;\n", {"-mode", "gist", "-s"}, @@ -108,7 +111,16 @@ namespace Test { namespace FlatZinc { const std::string& expected, bool allSolutions, std::vector cmdlineOpt, OutputCheck check, BeforeRun before) - : Base("FlatZinc::"+name), _name(name), _source(source), _expected(expected), + : FlatZincTest(TestTag::normal, name, source, expected, allSolutions, + cmdlineOpt, check, before) {} + + FlatZincTest::FlatZincTest(TestTags tags, const std::string& name, + const std::string& source, + const std::string& expected, bool allSolutions, + std::vector cmdlineOpt, + OutputCheck check, BeforeRun before) + : Base("FlatZinc::"+name, tags), _name(name), _source(source), + _expected(expected), _allSolutions(allSolutions), _cmdlineOpt(cmdlineOpt), _check(check), _before(before) {} @@ -116,7 +128,14 @@ namespace Test { namespace FlatZinc { const std::string& source, std::vector cmdlineOpt, std::string expectedMessage) - : FlatZincTest(name, source, "", false, cmdlineOpt), + : FlatZincErrorTest(TestTag::normal, name, source, cmdlineOpt, + expectedMessage) {} + + FlatZincErrorTest::FlatZincErrorTest(TestTags tags, const std::string& name, + const std::string& source, + std::vector cmdlineOpt, + std::string expectedMessage) + : FlatZincTest(tags, name, source, "", false, cmdlineOpt), _expectedMessage(expectedMessage) {} bool diff --git a/test/flatzinc.hh b/test/flatzinc.hh index 4295a007e8..98716ba380 100644 --- a/test/flatzinc.hh +++ b/test/flatzinc.hh @@ -70,6 +70,13 @@ namespace Test { std::vector cmdlineOpt = {}, OutputCheck check = OutputCheck(), BeforeRun before = BeforeRun()); + /// Construct and register a test with explicitly assigned tags + FlatZincTest(TestTags tags, const std::string& name, + const std::string& source, const std::string& expected, + bool allSolutions = false, + std::vector cmdlineOpt = {}, + OutputCheck check = OutputCheck(), + BeforeRun before = BeforeRun()); /// Perform test virtual bool run(void); }; @@ -82,6 +89,11 @@ namespace Test { FlatZincErrorTest(const std::string& name, const std::string& source, std::vector cmdlineOpt = {}, std::string expectedMessage = ""); + /// Construct and register an error test with explicitly assigned tags + FlatZincErrorTest(TestTags tags, const std::string& name, + const std::string& source, + std::vector cmdlineOpt = {}, + std::string expectedMessage = ""); /// Perform test virtual bool run(void); }; diff --git a/test/flatzinc/blackbox.cpp b/test/flatzinc/blackbox.cpp index 9f6acbe696..7a1d443f77 100644 --- a/test/flatzinc/blackbox.cpp +++ b/test/flatzinc/blackbox.cpp @@ -256,7 +256,9 @@ namespace Test { namespace FlatZinc { namespace Blackbox { class NativeProtocol : public Base { public: - NativeProtocol(void) : Base("FlatZinc::blackbox::native_protocol") {} + NativeProtocol(void) : Base("FlatZinc::blackbox::native_protocol") { + add_tags(TestTag::check); + } virtual bool run(void) { std::vector int_input{-2}; std::vector float_input{1.25}; @@ -372,7 +374,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { (void) new NativeProtocol; - (void) new FlatZincErrorTest("blackbox::malformed_annotation", + (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::malformed_annotation", std::string(blackbox_decl) + "var 0..1: y;\n" "constraint gecode_blackbox([], [], [y], []) :: " @@ -384,7 +386,7 @@ namespace Test { namespace FlatZinc { const char* exec = std::getenv("GECODE_TEST_BLACKBOX_EXEC"); if (exec != nullptr) { const std::string executable(exec); - (void) new FlatZincTest("blackbox::constant_value", + (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::constant_value", std::string(blackbox_decl) + "var 7..7: y :: output_var;\n" "constraint gecode_blackbox([], [], [y], []) :: " + @@ -392,7 +394,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", "y = 7;\n----------\n"); - (void) new FlatZincTest("blackbox::constant_value_unsat", + (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::constant_value_unsat", std::string(blackbox_decl) + "var 8..8: y;\n" "constraint gecode_blackbox([], [], [y], []) :: " + @@ -400,7 +402,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", "=====UNSATISFIABLE=====\n"); - (void) new FlatZincTest("blackbox::reason_independent_bounds", + (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::reason_independent_bounds", std::string(blackbox_bounds_decl) + "var 5..5: x :: output_var;\n" "constraint gecode_blackbox_bounds([x], [], [1,0,0]) :: " + @@ -408,7 +410,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", "x = 5;\n----------\n"); - (void) new FlatZincTest("blackbox::reason_independent_bounds_unsat", + (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::reason_independent_bounds_unsat", std::string(blackbox_bounds_decl) + "var 6..6: x;\n" "constraint gecode_blackbox_bounds([x], [], [1,0,0]) :: " + @@ -416,7 +418,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", "=====UNSATISFIABLE=====\n"); - (void) new FlatZincTest("blackbox::reason_dependent_bounds", + (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::reason_dependent_bounds", std::string(blackbox_bounds_decl) + "var 5..5: x :: output_var;\n" "constraint gecode_blackbox_bounds([x], [], [1,1,1,1,0]) :: " + @@ -424,7 +426,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", "x = 5;\n----------\n"); - (void) new FlatZincTest("blackbox::bounds_rescheduled_after_branch", + (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::bounds_rescheduled_after_branch", std::string(blackbox_bounds_decl) + "var 0..1: x :: output_var;\n" "var 0..5: y :: output_var;\n" @@ -438,7 +440,7 @@ namespace Test { namespace FlatZinc { false, {"-a"}); #ifdef GECODE_HAS_FLOAT_VARS - (void) new FlatZincErrorTest("blackbox::missing_bounds_reason_entry", + (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::missing_bounds_reason_entry", std::string(blackbox_bounds_decl) + "var 0..10: x;\n" "var 0.0..10.0: y;\n" @@ -447,7 +449,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", {}, "missing explained variable entry"); #endif - (void) new FlatZincErrorTest("blackbox::duplicate_bounds_reason_entry", + (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::duplicate_bounds_reason_entry", std::string(blackbox_bounds_decl) + "var 0..10: x;\n" "var 0..10: y;\n" @@ -455,7 +457,7 @@ namespace Test { namespace FlatZinc { fixture_annotation("exec", executable, {"bounds4"}) + ";\n" "solve satisfy;\n", {}, "duplicate explained variable index"); - (void) new FlatZincErrorTest("blackbox::invalid_bounds_reason_code", + (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::invalid_bounds_reason_code", std::string(blackbox_bounds_decl) + "var 0..10: x;\n" "constraint gecode_blackbox_bounds([x], [], [1,1,1,0,0]) :: " + @@ -463,7 +465,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", {}, "dependency bound code is out of range"); #ifdef GECODE_HAS_FLOAT_VARS - (void) new FlatZincErrorTest("blackbox::invalid_float_output", + (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::invalid_float_output", std::string(blackbox_decl) + "var 0.0..10.0: y;\n" "constraint gecode_blackbox([], [], [], [y]) :: " + @@ -471,13 +473,13 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", {}, "Failed to read output float 0"); #endif - (void) new FlatZincErrorTest("blackbox::nul_output", + (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::nul_output", std::string(blackbox_decl) + "constraint gecode_blackbox([], [], [], []) :: " + fixture_annotation("exec", executable, {"nul"}) + ";\n" "solve satisfy;\n", {}, "response contains NUL data"); - (void) new FlatZincErrorTest("blackbox::malformed_exec_parallel", + (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::malformed_exec_parallel", std::string(blackbox_decl) + "var 0..1: x :: output_var;\n" "var 0..1: y :: output_var;\n" @@ -506,7 +508,7 @@ namespace Test { namespace FlatZinc { expected = "integer 0 is outside Gecode's integer range"; break; } - (void) new FlatZincErrorTest( + (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check), "blackbox::native_exec_fault_" + std::to_string(kind), std::string(blackbox_decl) + "var " + std::to_string(kind) + ".." + std::to_string(kind) + @@ -526,7 +528,7 @@ namespace Test { namespace FlatZinc { #if defined(GECODE_HAS_POSIX_BLACKBOX_EXEC) const std::string descendant_log = fixture_log("exec_descendant"); if (!descendant_log.empty()) { - (void) new FlatZincTest("blackbox::native_exec_descendant_cleanup", + (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::native_exec_descendant_cleanup", std::string(blackbox_decl) + "var 1..1: y :: output_var;\n" "constraint gecode_blackbox([], [], [y], []) :: " + @@ -542,7 +544,7 @@ namespace Test { namespace FlatZinc { #endif } - (void) new FlatZincErrorTest("blackbox::missing_exec_parallel", + (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::missing_exec_parallel", std::string(blackbox_decl) + "var 0..1: x :: output_var;\n" "var 0..1: y :: output_var;\n" @@ -552,7 +554,7 @@ namespace Test { namespace FlatZinc { "satisfy;\n", {"-p", "2"}, "starting blackbox process failed"); - (void) new FlatZincErrorTest("blackbox::missing_exec_root_status", + (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::missing_exec_root_status", std::string(blackbox_decl) + "var 0..0: x :: output_var;\n" "var 0..1: y :: output_var;\n" @@ -567,7 +569,7 @@ namespace Test { namespace FlatZinc { const std::string library(dll); const std::string dll_model_log = fixture_log("dll_model"); if (!dll_model_log.empty()) { - (void) new FlatZincTest("blackbox::native_dll_per_constraint", + (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::native_dll_per_constraint", std::string(blackbox_decl) + "var 1..1: a :: output_var;\n" "var 1..1: b :: output_var;\n" @@ -594,7 +596,7 @@ namespace Test { namespace FlatZinc { #endif #ifdef GECODE_HAS_FLOAT_VARS - (void) new FlatZincErrorTest("blackbox::native_dll_nonfinite", + (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::native_dll_nonfinite", std::string(blackbox_decl) + "var 0.0..1.0: y;\n" "constraint gecode_blackbox([], [], [], [y]) :: " + diff --git a/test/flatzinc/magicsq_3.cpp b/test/flatzinc/magicsq_3.cpp index 6a6e34c48e..27f40f7737 100755 --- a/test/flatzinc/magicsq_3.cpp +++ b/test/flatzinc/magicsq_3.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("magic_square::3", + (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"magic_square::3", "predicate all_different_int(array [int] of var int: x);\n\ predicate all_equal_int(array [int] of var int: x);\n\ predicate among(var int: n, array [int] of var int: x, set of int: v);\n\ diff --git a/test/flatzinc/magicsq_4.cpp b/test/flatzinc/magicsq_4.cpp index 2bea231a5e..807200b1e4 100755 --- a/test/flatzinc/magicsq_4.cpp +++ b/test/flatzinc/magicsq_4.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("magic_square::4", + (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"magic_square::4", "predicate all_different_int(array [int] of var int: x);\n\ predicate all_equal_int(array [int] of var int: x);\n\ predicate among(var int: n, array [int] of var int: x, set of int: v);\n\ diff --git a/test/flatzinc/magicsq_5.cpp b/test/flatzinc/magicsq_5.cpp index 67d7f0679b..6ab2b86e1a 100644 --- a/test/flatzinc/magicsq_5.cpp +++ b/test/flatzinc/magicsq_5.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("magic_square::5", + (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"magic_square::5", "predicate all_different_int(array [int] of var int: x);\n\ predicate all_equal_int(array [int] of var int: x);\n\ predicate among(var int: n, array [int] of var int: x, set of int: v);\n\ diff --git a/test/flatzinc/oss.cpp b/test/flatzinc/oss.cpp index bbd0fdbf63..541e206b61 100644 --- a/test/flatzinc/oss.cpp +++ b/test/flatzinc/oss.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("oss", + (void) new FlatZincTest(TestTag::sweep,"oss", "predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/packing.cpp b/test/flatzinc/packing.cpp index 973cfac414..cce832a6e4 100644 --- a/test/flatzinc/packing.cpp +++ b/test/flatzinc/packing.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("packing", + (void) new FlatZincTest(TestTag::sweep,"packing", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/radiation.cpp b/test/flatzinc/radiation.cpp index 29589d59d4..c583d75875 100644 --- a/test/flatzinc/radiation.cpp +++ b/test/flatzinc/radiation.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("radiation", + (void) new FlatZincTest(TestTag::sweep,"radiation", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/steiner_triples.cpp b/test/flatzinc/steiner_triples.cpp index 55c513c6a5..7beee4cd38 100644 --- a/test/flatzinc/steiner_triples.cpp +++ b/test/flatzinc/steiner_triples.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("steiner_triples", + (void) new FlatZincTest(TestTag::sweep,"steiner_triples", "predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/template_design.cpp b/test/flatzinc/template_design.cpp index 7c089981cf..e3c33c16af 100644 --- a/test/flatzinc/template_design.cpp +++ b/test/flatzinc/template_design.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("template_design", + (void) new FlatZincTest(TestTag::sweep,"template_design", "predicate all_different_int(array [int] of var int: x);\n\ predicate all_equal_int(array [int] of var int: x);\n\ predicate among(var int: n, array [int] of var int: x, set of int: v);\n\ diff --git a/test/flatzinc/tenpenki_1.cpp b/test/flatzinc/tenpenki_1.cpp index 68890a63b3..9e9521a4f3 100644 --- a/test/flatzinc/tenpenki_1.cpp +++ b/test/flatzinc/tenpenki_1.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("tenpenki::1", + (void) new FlatZincTest(TestTag::sweep,"tenpenki::1", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/tenpenki_2.cpp b/test/flatzinc/tenpenki_2.cpp index c244be6c8c..791a1b88ba 100644 --- a/test/flatzinc/tenpenki_2.cpp +++ b/test/flatzinc/tenpenki_2.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("tenpenki::1", + (void) new FlatZincTest(TestTag::sweep,"tenpenki::1", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/tenpenki_3.cpp b/test/flatzinc/tenpenki_3.cpp index d56e56dff1..bbceae472b 100644 --- a/test/flatzinc/tenpenki_3.cpp +++ b/test/flatzinc/tenpenki_3.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("tenpenki::3", + (void) new FlatZincTest(TestTag::sweep,"tenpenki::3", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/tenpenki_4.cpp b/test/flatzinc/tenpenki_4.cpp index 06b516ca30..ee9e2e6b47 100644 --- a/test/flatzinc/tenpenki_4.cpp +++ b/test/flatzinc/tenpenki_4.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("tenpenki::4", + (void) new FlatZincTest(TestTag::sweep,"tenpenki::4", "predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/tenpenki_5.cpp b/test/flatzinc/tenpenki_5.cpp index 6227db4c82..bffbd629fe 100644 --- a/test/flatzinc/tenpenki_5.cpp +++ b/test/flatzinc/tenpenki_5.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("tenpenki::5", + (void) new FlatZincTest(TestTag::sweep,"tenpenki::5", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/tenpenki_6.cpp b/test/flatzinc/tenpenki_6.cpp index f2eb06cdd7..9bb7904425 100644 --- a/test/flatzinc/tenpenki_6.cpp +++ b/test/flatzinc/tenpenki_6.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("tenpenki::6", + (void) new FlatZincTest(TestTag::sweep,"tenpenki::6", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/timetabling.cpp b/test/flatzinc/timetabling.cpp index 06ac050619..f02ce689e8 100644 --- a/test/flatzinc/timetabling.cpp +++ b/test/flatzinc/timetabling.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("timetabling", + (void) new FlatZincTest(TestTag::sweep,"timetabling", std::string("predicate all_different_int(array [int] of var int: x);\n\ predicate all_equal_int(array [int] of var int: x);\n\ predicate among(var int: n, array [int] of var int: x, set of int: v);\n\ diff --git a/test/flatzinc/trucking.cpp b/test/flatzinc/trucking.cpp index 06fb86ccae..fa9394cae4 100644 --- a/test/flatzinc/trucking.cpp +++ b/test/flatzinc/trucking.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest("trucking", + (void) new FlatZincTest(TestTag::sweep,"trucking", "predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/float.hh b/test/float.hh index 4576978c90..e496b5484c 100644 --- a/test/float.hh +++ b/test/float.hh @@ -296,6 +296,10 @@ namespace Test { Test(const std::string& s, int a, const Gecode::FloatVal& d, Gecode::FloatNum st, AssignmentType at, bool r); + /// Construct and register a test with explicitly assigned tags + Test(TestTags tags, const std::string& s, int a, + const Gecode::FloatVal& d, Gecode::FloatNum st, + AssignmentType at, bool r); /** * \brief Constructor * @@ -307,6 +311,10 @@ namespace Test { Gecode::FloatNum min, Gecode::FloatNum max, Gecode::FloatNum st, AssignmentType at, bool r); + /// Construct and register a test with explicitly assigned tags + Test(TestTags tags, const std::string& s, int a, + Gecode::FloatNum min, Gecode::FloatNum max, + Gecode::FloatNum st, AssignmentType at, bool r); /// Create assignment virtual Assignment* assignment(void) const; /// Complete the current assignment to get a feasible one (which satisfies all constraint). diff --git a/test/float.hpp b/test/float.hpp index f84273e509..4a05788233 100755 --- a/test/float.hpp +++ b/test/float.hpp @@ -170,25 +170,37 @@ namespace Test { namespace Float { return reified && ((rms & (1 << Gecode::RM_PMI)) != 0); } inline - Test::Test(const std::string& s, int a, const Gecode::FloatVal& d, - Gecode::FloatNum st, AssignmentType at, - bool r) - : Base("Float::"+s), arity(a), dom(d), step(st), assignmentType(at), + Test::Test(TestTags tags, const std::string& s, int a, + const Gecode::FloatVal& d, Gecode::FloatNum st, + AssignmentType at, bool r) + : Base("Float::"+s, tags), arity(a), dom(d), step(st), assignmentType(at), reified(r), rms((1 << Gecode::RM_EQV) | (1 << Gecode::RM_IMP) | (1 << Gecode::RM_PMI)), testsearch(true), testfix(true), testsubsumed(true) {} + inline + Test::Test(const std::string& s, int a, const Gecode::FloatVal& d, + Gecode::FloatNum st, AssignmentType at, + bool r) + : Test(TestTag::normal,s,a,d,st,at,r) {} + + inline + Test::Test(TestTags tags, const std::string& s, int a, + Gecode::FloatNum min, Gecode::FloatNum max, + Gecode::FloatNum st, AssignmentType at, bool r) + : Base("Float::"+s, tags), arity(a), dom(min,max), step(st), + assignmentType(at), reified(r), + rms((1 << Gecode::RM_EQV) | + (1 << Gecode::RM_IMP) | + (1 << Gecode::RM_PMI)), + testsearch(true), testfix(true), testsubsumed(true) {} + inline Test::Test(const std::string& s, int a, Gecode::FloatNum min, Gecode::FloatNum max, Gecode::FloatNum st, AssignmentType at, bool r) - : Base("Float::"+s), arity(a), dom(min,max), step(st), - assignmentType(at), reified(r), - rms((1 << Gecode::RM_EQV) | - (1 << Gecode::RM_IMP) | - (1 << Gecode::RM_PMI)), - testsearch(true), testfix(true), testsubsumed(true) {} + : Test(TestTag::normal,s,a,min,max,st,at,r) {} inline std::string @@ -309,4 +321,3 @@ namespace Test { namespace Float { }} // STATISTICS: test-float - diff --git a/test/float/arithmetic.cpp b/test/float/arithmetic.cpp index 7044a2543a..d438b959c8 100755 --- a/test/float/arithmetic.cpp +++ b/test/float/arithmetic.cpp @@ -134,7 +134,9 @@ namespace Test { namespace Float { public: /// Create and register test PositiveNRootBounds(void) - : Base("Float::Arithmetic::PositiveNRootBounds") {} + : Base("Float::Arithmetic::PositiveNRootBounds") { + add_tags(TestTag::check); + } /// Run test under every supported IEEE-754 rounding mode virtual bool run(void) { const int oldMode = std::fegetround(); @@ -364,7 +366,9 @@ namespace Test { namespace Float { } public: /// Create and register test - PowConsistency(void) : Base("Float::Arithmetic::PowConsistency") {} + PowConsistency(void) : Base("Float::Arithmetic::PowConsistency") { + add_tags(TestTag::check); + } /// Run zero and fixpoint regressions virtual bool run(void) { bool result = true; @@ -486,7 +490,9 @@ namespace Test { namespace Float { public: /// Create and register test MultZeroEndpoint(void) - : Base("Float::Arithmetic::MultZeroEndpoint") {} + : Base("Float::Arithmetic::MultZeroEndpoint") { + add_tags(TestTag::check); + } /// Run sign, symmetry, signed-zero, and zero-product cases virtual bool run(void) { bool result = true; @@ -525,7 +531,7 @@ namespace Test { namespace Float { public: /// Create and register test MultXYZ(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Mult::XYZ::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Mult::XYZ::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[1], x[2]); @@ -544,7 +550,12 @@ namespace Test { namespace Float { public: /// Create and register test MultXYZSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Mult::XYZ::Sol::"+s,3,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Mult::XYZ::Sol::"+s,3,d,st,EXTEND_ASSIGNMENT,false) { + if (s == "C") { + tags(TestTag::normal); + add_tags(TestTag::check); + } + } /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[1], x[2]); @@ -570,7 +581,7 @@ namespace Test { namespace Float { public: /// Create and register test MultXXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Mult::XXY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Mult::XXY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[0], x[1]); @@ -586,7 +597,7 @@ namespace Test { namespace Float { public: /// Create and register test MultXXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Mult::XXY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Mult::XXY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[0], x[1]); @@ -612,7 +623,7 @@ namespace Test { namespace Float { public: /// Create and register test MultXYX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Mult::XYX::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Mult::XYX::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[1], x[0]); @@ -628,7 +639,7 @@ namespace Test { namespace Float { public: /// Create and register test MultXYY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Mult::XYY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Mult::XYY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[1], x[1]); @@ -644,7 +655,7 @@ namespace Test { namespace Float { public: /// Create and register test MultXXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Mult::XXX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Mult::XXX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[0], x[0]); @@ -660,7 +671,8 @@ namespace Test { namespace Float { public: /// Create and register test Div(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Div::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Arithmetic::Div::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] / x[1], x[2]); @@ -679,7 +691,7 @@ namespace Test { namespace Float { public: /// Create and register test DivSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Div::Sol::"+s,3,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Div::Sol::"+s,3,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] / x[1], x[2]); @@ -705,7 +717,7 @@ namespace Test { namespace Float { public: /// Create and register test SqrXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Sqr::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Sqr::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[0], x[1]); @@ -724,7 +736,7 @@ namespace Test { namespace Float { public: /// Create and register test SqrXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Sqr::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Sqr::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[0], x[1]); @@ -750,7 +762,8 @@ namespace Test { namespace Float { public: /// Create and register test SqrXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Sqr::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Arithmetic::Sqr::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[0], x[0]); @@ -766,7 +779,7 @@ namespace Test { namespace Float { public: /// Create and register test SqrtXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Sqrt::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Sqrt::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { switch (cmp(x[0], Gecode::FRT_GQ, 0.0)) { @@ -790,7 +803,7 @@ namespace Test { namespace Float { public: /// Create and register test SqrtXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Sqrt::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Sqrt::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { switch (cmp(x[0], Gecode::FRT_GQ, 0.0)) { @@ -821,7 +834,8 @@ namespace Test { namespace Float { public: /// Create and register test SqrtXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Sqrt::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Arithmetic::Sqrt::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { switch (cmp(x[0], Gecode::FRT_GQ, 0.0)) { @@ -843,7 +857,7 @@ namespace Test { namespace Float { public: /// Create and register test PowXY(const std::string& s, const Gecode::FloatVal& d, unsigned int _n, Gecode::FloatNum st) - : Test("Arithmetic::Pow::N::"+str(_n)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), n(_n) {} + : Test(TestTag::sweep,"Arithmetic::Pow::N::"+str(_n)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), n(_n) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(pow(x[0],n), x[1]); @@ -863,7 +877,12 @@ namespace Test { namespace Float { public: /// Create and register test PowXYSol(const std::string& s, const Gecode::FloatVal& d, unsigned int _n, Gecode::FloatNum st) - : Test("Arithmetic::Pow::N::"+str(_n)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), n(_n) {} + : Test(TestTag::sweep,"Arithmetic::Pow::N::"+str(_n)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), n(_n) { + if ((_n == 2) && (s == "C")) { + tags(TestTag::normal); + add_tags(TestTag::check); + } + } /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(pow(x[0],n), x[1]); @@ -890,7 +909,7 @@ namespace Test { namespace Float { public: /// Create and register test PowXX(const std::string& s, const Gecode::FloatVal& d, unsigned int _n, Gecode::FloatNum st) - : Test("Arithmetic::Pow::N::"+str(_n)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), n(_n) {} + : Test(TestTag::sweep,"Arithmetic::Pow::N::"+str(_n)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), n(_n) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(pow(x[0],n), x[0]); @@ -907,7 +926,7 @@ namespace Test { namespace Float { public: /// Create and register test NRootXY(const std::string& s, const Gecode::FloatVal& d, unsigned int _n, Gecode::FloatNum st) - : Test("Arithmetic::NRoot::N::"+str(_n)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), n(_n) {} + : Test(TestTag::sweep,"Arithmetic::NRoot::N::"+str(_n)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), n(_n) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((n == 0) || (x[0].min() < 0.0)) @@ -929,7 +948,12 @@ namespace Test { namespace Float { public: /// Create and register test NRootXYSol(const std::string& s, const Gecode::FloatVal& d, unsigned int _n, Gecode::FloatNum st) - : Test("Arithmetic::NRoot::N::"+str(_n)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), n(_n) {} + : Test(TestTag::sweep,"Arithmetic::NRoot::N::"+str(_n)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), n(_n) { + if ((_n == 2) && (s == "C")) { + tags(TestTag::normal); + add_tags(TestTag::check); + } + } /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((n == 0) || (x[0].min() < 0.0)) @@ -960,7 +984,7 @@ namespace Test { namespace Float { public: /// Create and register test NRootXX(const std::string& s, const Gecode::FloatVal& d, unsigned int _n, Gecode::FloatNum st) - : Test("Arithmetic::NRoot::N::"+str(_n)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), n(_n) {} + : Test(TestTag::sweep,"Arithmetic::NRoot::N::"+str(_n)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), n(_n) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((n == 0) || (x[0].min() < 0)) @@ -978,7 +1002,7 @@ namespace Test { namespace Float { public: /// Create and register test AbsXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Abs::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Abs::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(abs(x[0]), x[1]); @@ -997,7 +1021,8 @@ namespace Test { namespace Float { public: /// Create and register test AbsXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Abs::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Arithmetic::Abs::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(abs(x[0]), x[0]); @@ -1013,7 +1038,7 @@ namespace Test { namespace Float { public: /// Create and register test MinXYZ(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Min::Bin::XYZ::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Min::Bin::XYZ::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(x[0],x[1]), x[2]); @@ -1032,7 +1057,7 @@ namespace Test { namespace Float { public: /// Create and register test MinXXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Min::Bin::XXY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Min::Bin::XXY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(x[0],x[0]), x[1]); @@ -1048,7 +1073,7 @@ namespace Test { namespace Float { public: /// Create and register test MinXYX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Min::Bin::XYX::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Min::Bin::XYX::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(x[0],x[1]), x[0]); @@ -1064,7 +1089,7 @@ namespace Test { namespace Float { public: /// Create and register test MinXYY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Min::Bin::XYY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Min::Bin::XYY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(x[0],x[1]), x[1]); @@ -1080,7 +1105,8 @@ namespace Test { namespace Float { public: /// Create and register test MinXXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Min::Bin::XXX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Arithmetic::Min::Bin::XXX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(x[0],x[0]), x[0]); @@ -1096,7 +1122,7 @@ namespace Test { namespace Float { public: /// Create and register test MaxXYZ(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Max::Bin::XYZ::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Max::Bin::XYZ::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(x[0],x[1]), x[2]); @@ -1115,7 +1141,7 @@ namespace Test { namespace Float { public: /// Create and register test MaxXXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Max::Bin::XXY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Max::Bin::XXY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(x[0],x[0]), x[1]); @@ -1131,7 +1157,7 @@ namespace Test { namespace Float { public: /// Create and register test MaxXYX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Max::Bin::XYX::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Max::Bin::XYX::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(x[0],x[1]), x[0]); @@ -1147,7 +1173,7 @@ namespace Test { namespace Float { public: /// Create and register test MaxXYY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Max::Bin::XYY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Max::Bin::XYY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(x[0],x[1]), x[1]); @@ -1163,7 +1189,8 @@ namespace Test { namespace Float { public: /// Create and register test MaxXXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Arithmetic::Max::Bin::XXX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Arithmetic::Max::Bin::XXX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(x[0],x[0]), x[0]); @@ -1179,7 +1206,7 @@ namespace Test { namespace Float { public: /// Create and register test MinNary(void) - : Test("Arithmetic::Min::Nary",4,-4,4,0.5,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Min::Nary",4,-4,4,0.5,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(min(x[0],x[1]),x[2]), x[3]); @@ -1200,7 +1227,7 @@ namespace Test { namespace Float { public: /// Create and register test MinNaryShared(void) - : Test("Arithmetic::Min::Nary::Shared",3,-4,4,0.5,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Min::Nary::Shared",3,-4,4,0.5,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(min(x[0],x[1]),x[2]), x[1]); @@ -1218,7 +1245,7 @@ namespace Test { namespace Float { public: /// Create and register test MaxNary(void) - : Test("Arithmetic::Max::Nary",4,-4,4,0.5,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Max::Nary",4,-4,4,0.5,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(max(x[0],x[1]),x[2]), x[3]); @@ -1239,7 +1266,7 @@ namespace Test { namespace Float { public: /// Create and register test MaxNaryShared(void) - : Test("Arithmetic::Max::Nary::Shared",3,-4,4,0.5,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Arithmetic::Max::Nary::Shared",3,-4,4,0.5,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(max(x[0],x[1]),x[2]), x[1]); diff --git a/test/float/linear.cpp b/test/float/linear.cpp index a20cc39276..8111250674 100644 --- a/test/float/linear.cpp +++ b/test/float/linear.cpp @@ -69,7 +69,9 @@ namespace Test { namespace Float { FloatFloat(const std::string& s, const Gecode::FloatVal& d, const Gecode::FloatValArgs& a0, Gecode::FloatRelType frt0, Gecode::FloatNum c0, Gecode::FloatNum st) - : Test("Linear::Float::"+ + : Test((s == "11") && (frt0 == Gecode::FRT_EQ) && + (c0 == 0.0) && (a0.size() == 1) + ? TestTag::normal : TestTag::sweep,"Linear::Float::"+ str(frt0)+"::"+s+"::"+str(c0)+"::" +str(a0.size()), a0.size(),d,st,CPLT_ASSIGNMENT,true), @@ -130,7 +132,9 @@ namespace Test { namespace Float { /// Create and register test FloatVar(const std::string& s, const Gecode::FloatVal& d, const Gecode::FloatValArgs& a0, Gecode::FloatRelType frt0, Gecode::FloatNum st) - : Test("Linear::Var::"+ + : Test((s == "11") && (frt0 == Gecode::FRT_EQ) && + (a0.size() == 1) ? TestTag::normal : TestTag::sweep, + "Linear::Var::"+ str(frt0)+"::"+s+"::"+str(a0.size()), a0.size()+1,d,st,CPLT_ASSIGNMENT,true), a(a0), frt(frt0) { diff --git a/test/float/mm-lin.cpp b/test/float/mm-lin.cpp index 1007b9826e..0168e67a0a 100644 --- a/test/float/mm-lin.cpp +++ b/test/float/mm-lin.cpp @@ -99,7 +99,8 @@ namespace Test { namespace Float { public: /// Create and register test LinExpr(const LinInstr* lis0, const std::string& s) - : Test("Float::","MiniModel::LinExpr::"+s,4,-3,3), + : Test(s == "000" ? TestTag::normal : TestTag::sweep, + "Float::","MiniModel::LinExpr::"+s,4,-3,3), lis(lis0) { testfix = false; } diff --git a/test/float/transcendental.cpp b/test/float/transcendental.cpp index 2f69d11371..367f66e64d 100644 --- a/test/float/transcendental.cpp +++ b/test/float/transcendental.cpp @@ -51,7 +51,7 @@ namespace Test { namespace Float { public: /// Create and register test ExpXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Transcendental::Exp::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Transcendental::Exp::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(exp(x[0]), x[1]); @@ -70,7 +70,7 @@ namespace Test { namespace Float { public: /// Create and register test ExpXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Transcendental::Exp::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Transcendental::Exp::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(exp(x[0]), x[1]); @@ -96,7 +96,8 @@ namespace Test { namespace Float { public: /// Create and register test ExpXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Transcendental::Exp::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Transcendental::Exp::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(exp(x[0]), x[0]); @@ -112,7 +113,7 @@ namespace Test { namespace Float { public: /// Create and register test LogXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Transcendental::Log::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Transcendental::Log::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if (x[0].max() < 0.0) @@ -133,7 +134,7 @@ namespace Test { namespace Float { public: /// Create and register test LogXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Transcendental::Log::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Transcendental::Log::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if (x[0].max() < 0.0) @@ -162,7 +163,8 @@ namespace Test { namespace Float { public: /// Create and register test LogXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Transcendental::Log::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Transcendental::Log::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if (x[0].max() < 0.0) @@ -181,7 +183,7 @@ namespace Test { namespace Float { public: /// Create and register test LogNXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum _base, Gecode::FloatNum st) - : Test("Transcendental::Log::N::"+str(_base)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), base(_base) {} + : Test(TestTag::sweep,"Transcendental::Log::N::"+str(_base)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), base(_base) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].max() <= 0.0) || (base <= 0.0)) @@ -200,7 +202,7 @@ namespace Test { namespace Float { public: /// Create and register test LogNXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum _base, Gecode::FloatNum st) - : Test("Transcendental::Log::N::"+str(_base)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), base(_base) {} + : Test(TestTag::sweep,"Transcendental::Log::N::"+str(_base)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), base(_base) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].max() <= 0.0) || (base <= 0.0)) @@ -231,7 +233,7 @@ namespace Test { namespace Float { public: /// Create and register test LogNXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum _base, Gecode::FloatNum st) - : Test("Transcendental::Log::N::"+str(_base)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), base(_base) {} + : Test(TestTag::sweep,"Transcendental::Log::N::"+str(_base)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), base(_base) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].max() <= 0.0) || (base <= 0.0)) @@ -250,7 +252,7 @@ namespace Test { namespace Float { public: /// Create and register test PowXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum _base, Gecode::FloatNum st) - : Test("Transcendental::Pow::N::"+str(_base)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), base(_base) {} + : Test(TestTag::sweep,"Transcendental::Pow::N::"+str(_base)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), base(_base) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if (base <= 0.0) @@ -269,7 +271,7 @@ namespace Test { namespace Float { public: /// Create and register test PowXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum _base, Gecode::FloatNum st) - : Test("Transcendental::Pow::N::"+str(_base)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), base(_base) {} + : Test(TestTag::sweep,"Transcendental::Pow::N::"+str(_base)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), base(_base) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if (base <= 0.0) @@ -299,7 +301,10 @@ namespace Test { namespace Float { public: /// Create and register test PowXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum _base, Gecode::FloatNum st) - : Test("Transcendental::Pow::N::"+str(_base)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), base(_base) {} + : Test((_base == 1.5) && (s == "A") + ? TestTag::normal : TestTag::sweep, + "Transcendental::Pow::N::"+str(_base)+"::XX::"+s, + 1,d,st,CPLT_ASSIGNMENT,false), base(_base) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].max() <= 0.0) || (base <= 0.0)) diff --git a/test/float/trigonometric.cpp b/test/float/trigonometric.cpp index 97381d3a73..61a49dd814 100644 --- a/test/float/trigonometric.cpp +++ b/test/float/trigonometric.cpp @@ -51,7 +51,7 @@ namespace Test { namespace Float { public: /// Create and register test SinXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::Sin::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Trigonometric::Sin::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(sin(x[0]), x[1]); @@ -70,7 +70,7 @@ namespace Test { namespace Float { public: /// Create and register test SinXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::Sin::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Trigonometric::Sin::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(sin(x[0]), x[1]); @@ -96,7 +96,8 @@ namespace Test { namespace Float { public: /// Create and register test SinXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::Sin::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Trigonometric::Sin::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(sin(x[0]), x[0]); @@ -112,7 +113,7 @@ namespace Test { namespace Float { public: /// Create and register test CosXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::Cos::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Trigonometric::Cos::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(cos(x[0]), x[1]); @@ -131,7 +132,7 @@ namespace Test { namespace Float { public: /// Create and register test CosXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::Cos::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Trigonometric::Cos::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(cos(x[0]), x[1]); @@ -157,7 +158,8 @@ namespace Test { namespace Float { public: /// Create and register test CosXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::Cos::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Trigonometric::Cos::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(cos(x[0]), x[0]); @@ -173,7 +175,7 @@ namespace Test { namespace Float { public: /// Create and register test TanXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::Tan::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Trigonometric::Tan::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(tan(x[0]), x[1]); @@ -192,7 +194,7 @@ namespace Test { namespace Float { public: /// Create and register test TanXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::Tan::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Trigonometric::Tan::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(tan(x[0]), x[1]); @@ -218,7 +220,8 @@ namespace Test { namespace Float { public: /// Create and register test TanXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::Tan::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Trigonometric::Tan::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(tan(x[0]), x[0]); @@ -234,7 +237,7 @@ namespace Test { namespace Float { public: /// Create and register test ASinXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::ASin::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Trigonometric::ASin::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].min() > 1.0) || (x[0].max() < -1.0)) @@ -255,7 +258,7 @@ namespace Test { namespace Float { public: /// Create and register test ASinXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::ASin::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Trigonometric::ASin::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].min() > 1.0) || (x[0].max() < -1.0)) @@ -285,7 +288,8 @@ namespace Test { namespace Float { public: /// Create and register test ASinXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::ASin::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Trigonometric::ASin::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].min() > 1.0) || (x[0].max() < -1.0)) @@ -303,7 +307,7 @@ namespace Test { namespace Float { public: /// Create and register test ACosXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::ACos::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Trigonometric::ACos::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].min() > 1.0) || (x[0].max() < -1.0)) @@ -324,7 +328,7 @@ namespace Test { namespace Float { public: /// Create and register test ACosXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::ACos::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Trigonometric::ACos::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].min() > 1.0) || (x[0].max() < -1.0)) @@ -354,7 +358,8 @@ namespace Test { namespace Float { public: /// Create and register test ACosXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::ACos::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Trigonometric::ACos::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].min() > 1.0) || (x[0].max() < -1.0)) @@ -372,7 +377,7 @@ namespace Test { namespace Float { public: /// Create and register test ATanXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::ATan::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Trigonometric::ATan::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(atan(x[0]), x[1]); @@ -391,7 +396,7 @@ namespace Test { namespace Float { public: /// Create and register test ATanXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::ATan::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTag::sweep,"Trigonometric::ATan::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(atan(x[0]), x[1]); @@ -417,7 +422,8 @@ namespace Test { namespace Float { public: /// Create and register test ATanXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test("Trigonometric::ATan::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Trigonometric::ATan::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(atan(x[0]), x[0]); diff --git a/test/gecode-tags.cpp b/test/gecode-tags.cpp deleted file mode 100644 index 5513ceb21d..0000000000 --- a/test/gecode-tags.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ -/* - * Main authors: - * Christian Schulte - * - * Contributing authors: - * Mikael Lagerkvist - * - * Copyright: - * Christian Schulte, 2026 - * - * This file is part of Gecode, the generic constraint - * development environment: - * http://www.gecode.org - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "test/test.hh" -#include "test/gecode-tags.hh" - -#include - -namespace Test { - - /// Patterns that reproduce the historic make check selection - static const char* const check_patterns[] = { - "Branch::Int::Dense::3", - "FlatZinc::Options", - "FlatZinc::magic_square", - "FlatZinc::blackbox", - "Float::Arithmetic::PositiveNRootBounds", - "Float::Arithmetic::PowConsistency", - "Float::Arithmetic::MultZeroEndpoint", - "Float::Arithmetic::Pow::N::2::XY::Sol::C", - "Float::Arithmetic::NRoot::N::2::XY::Sol::C", - "Float::Arithmetic::Mult::XYZ::Sol::C", - "Int::Arithmetic::Abs", - "Int::Arithmetic::ArgMax", - "Int::Arithmetic::Max::Nary", - "Int::Cumulative::Man::Fix::0::4", - "Int::Distinct::Random", - "Int::Extensional::TupleSet::Sparse::IncrementalDelta", - "Int::Extensional::TupleSet::Auto::DefaultDispatch", - "Int::Linear::Bool::Int::Lq", - "Int::MiniModel::LinExpr::Bool::352", - "NoGoods::Queens", - "Search::DFS::Sol::Binary::Nary::Binary::1::1::1", - "Set::Dom::Dom::Gr", - "Set::RelOp::ConstSSI::Union", - "Set::Sequence::SeqU1", - "Set::Wait", - nullptr - }; - - /// Representative cases retained from otherwise exhaustive sweep families - static const char* const normal_patterns[] = { - "Float::Arithmetic::Abs::XX::A", - "Float::Arithmetic::Div::A", - "Float::Arithmetic::Max::Bin::XXX::A", - "Float::Arithmetic::Min::Bin::XXX::A", - "Float::Arithmetic::Sqr::XX::A", - "Float::Arithmetic::Sqrt::XX::A", - "Float::Linear::Float::Eq::11::0::1", - "Float::Linear::Var::Eq::11::1", - "Float::MiniModel::LinExpr::000", - "Float::Transcendental::Exp::XX::A", - "Float::Transcendental::Log::XX::A", - "Float::Transcendental::Pow::N::1.5::XX::A", - "Float::Trigonometric::ACos::XX::A", - "Float::Trigonometric::ASin::XX::A", - "Float::Trigonometric::ATan::XX::A", - "Float::Trigonometric::Cos::XX::A", - "Float::Trigonometric::Sin::XX::A", - "Float::Trigonometric::Tan::XX::A", - "Int::Arithmetic::Nroot::XX::1::Bnd::A", - "Int::Arithmetic::Pow::XX::0::Bnd::A", - "Int::Channel::Bool::Multi::A", - "Int::Circuit::Cost::Dom::4::0", - "Int::Count::Distinct::Bnd::Dense", - "Int::Cumulative::Opt::Fix::-2147483646::-1", - "Int::Cumulative::Opt::Flex::-2147483646::4::0::2", - "Int::Distinct::Bnd::Dense", - "Int::Distinct::Dom::Dense", - "Int::Distinct::Offset::Dense::Bnd", - "Int::GCC::Int::All::Max::Bnd", - "Int::Linear::Int::Int::Eq::Bnd::11::0::1", - "Int::MiniModel::SetExpr::Const::000::0::0", - "Int::MiniModel::SetExpr::Expr::000::000::0", - "Int::NValues::Int::Int::Eq::1::0", - "Int::NoOverlap::Int::2::2::[1,1,1,1]::[1,1,1,1]", - "Int::Path::Cost::Dom::3::0", - "Int::Rel::Int::Array::Eq::0::4", - "Int::Unary::Man::Fix::-2147483646::[2,2,0,2,2]::Def+A", - "Int::Unary::Man::Flex::-2147483646::4::0::2::Def+A", - "Int::Unary::Opt::Fix::-2147483646::[2,2,0,2,2]::Def+A", - "Int::Unary::Opt::Flex::-2147483646::4::0::2::Def+A", - "Search::BAB::Sol::BalGr::Binary::Binary::Binary::1::1::1", - "Set::Branch::Dense::3", - "Set::Channel::Bool::1", - "Set::Element::Disjoint", - "Set::Precede::Multi::[1,2,3]", - "Set::Rel::Bin::Cmpl::S0", - "Set::RelOp::ConstISI::DUnion::Cmpl::0::0", - nullptr - }; - - /// Patterns for tests that are too heavy for the normal suite - static const char* const sweep_patterns[] = { - "FlatZinc::oss", - "FlatZinc::packing", - "FlatZinc::radiation", - "FlatZinc::steiner_triples", - "FlatZinc::template_design", - "FlatZinc::tenpenki", - "FlatZinc::timetabling", - "FlatZinc::trucking", - "Float::Arithmetic", - "Float::Linear::Float", - "Float::Linear::Var", - "Float::MiniModel::LinExpr", - "Float::Transcendental", - "Float::Trigonometric", - "Int::Arithmetic::Nroot", - "Int::Arithmetic::Pow", - "Int::Channel", - "Int::Circuit", - "Int::Count::Distinct", - "Int::Cumulative::Man", - "Int::Cumulative::Opt", - "Int::Distinct::Bnd", - "Int::Distinct::Dom", - "Int::Distinct::Offset", - "Int::Distinct::Pathological", - "Int::Extensional::TupleSet", - "Int::GCC", - "Int::Linear::Bool", - "Int::Linear::Int", - "Int::MiniModel::LinExpr", - "Int::MiniModel::SetExpr", - "Int::NValues::Int", - "Int::NoOverlap", - "Int::Path", - "Int::Rel::Int", - "Int::Unary", - "Search::BAB::Sol", - "Search::DFS::Sol", - "Set::Branch", - "Set::Channel", - "Set::Dom", - "Set::Element", - "Set::Precede", - "Set::Rel", - "Set::RelOp", - nullptr - }; - - static bool - matches_any_pattern(const std::string& name, - const char* const patterns[]) { - for (int i=0; patterns[i] != nullptr; i++) - if (name.find(patterns[i]) != std::string::npos) - return true; - return false; - } - - void - apply_gecode_test_tags(void) { - for (Base* test = Base::tests(); test != nullptr; - test = test->next()) { - const std::string& name = test->name(); - const bool check = matches_any_pattern(name, check_patterns); - const bool representative = matches_any_pattern(name, normal_patterns); - if (!check && !representative && - matches_any_pattern(name, sweep_patterns)) { - test->remove_tags(TestTag::normal); - test->add_tags(TestTag::sweep); - } - if (check) - test->add_tags(TestTag::check); - } - } - -} - -// STATISTICS: test-core diff --git a/test/gecode-tags.hh b/test/gecode-tags.hh deleted file mode 100644 index aea4e19c93..0000000000 --- a/test/gecode-tags.hh +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ -/* - * Main authors: - * Mikael Lagerkvist - * - * Copyright: - * Mikael Lagerkvist, 2026 - * - * This file is part of Gecode, the generic constraint - * development environment: - * http://www.gecode.org - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef GECODE_TEST_GECODE_TAGS_HH -#define GECODE_TEST_GECODE_TAGS_HH - -namespace Test { - - /// Apply Gecode's suite classification to its registered tests - void apply_gecode_test_tags(void); - -} - -#endif - -// STATISTICS: test-core diff --git a/test/int.hh b/test/int.hh index 6e36158718..c317b33d8e 100755 --- a/test/int.hh +++ b/test/int.hh @@ -306,6 +306,10 @@ namespace Test { Test(const std::string& p, const std::string& s, int a, const Gecode::IntSet& d, bool r=false, Gecode::IntPropLevel i=Gecode::IPL_DEF); + /// Construct and register a test with explicitly assigned tags + Test(TestTags tags, const std::string& p, const std::string& s, + int a, const Gecode::IntSet& d, bool r=false, + Gecode::IntPropLevel i=Gecode::IPL_DEF); /** * \brief Constructor * @@ -317,6 +321,10 @@ namespace Test { Test(const std::string& s, int a, const Gecode::IntSet& d, bool r=false, Gecode::IntPropLevel i=Gecode::IPL_DEF); + /// Construct and register a test with explicitly assigned tags + Test(TestTags tags, const std::string& s, + int a, const Gecode::IntSet& d, bool r=false, + Gecode::IntPropLevel i=Gecode::IPL_DEF); /** * \brief Constructor * @@ -328,6 +336,10 @@ namespace Test { Test(const std::string& p, const std::string& s, int a, int min, int max, bool r=false, Gecode::IntPropLevel i=Gecode::IPL_DEF); + /// Construct and register a test with explicitly assigned tags + Test(TestTags tags, const std::string& p, const std::string& s, + int a, int min, int max, bool r=false, + Gecode::IntPropLevel i=Gecode::IPL_DEF); /** * \brief Constructor * @@ -339,6 +351,10 @@ namespace Test { Test(const std::string& s, int a, int min, int max, bool r=false, Gecode::IntPropLevel i=Gecode::IPL_DEF); + /// Construct and register a test with explicitly assigned tags + Test(TestTags tags, const std::string& s, + int a, int min, int max, bool r=false, + Gecode::IntPropLevel i=Gecode::IPL_DEF); /** \brief Create the assignment generator (complete by default) * * An override changes the assignments checked, not the variable diff --git a/test/int.hpp b/test/int.hpp index 65a0e828ef..a4324232eb 100755 --- a/test/int.hpp +++ b/test/int.hpp @@ -161,10 +161,10 @@ namespace Test { namespace Int { return reified && ((rms & (1 << Gecode::RM_PMI)) != 0); } inline - Test::Test(const std::string& p, const std::string& s, + Test::Test(TestTags tags, const std::string& p, const std::string& s, int a, const Gecode::IntSet& d, bool r, Gecode::IntPropLevel i) - : Base(p+s), arity(a), dom(d), + : Base(p+s, tags), arity(a), dom(d), reified(r), rms((1 << Gecode::RM_EQV) | (1 << Gecode::RM_IMP) | (1 << Gecode::RM_PMI)), @@ -172,10 +172,16 @@ namespace Test { namespace Int { testsearch(true), testfix(true) {} inline - Test::Test(const std::string& s, + Test::Test(const std::string& p, const std::string& s, + int a, const Gecode::IntSet& d, bool r, + Gecode::IntPropLevel i) + : Test(TestTag::normal,p,s,a,d,r,i) {} + + inline + Test::Test(TestTags tags, const std::string& s, int a, const Gecode::IntSet& d, bool r, Gecode::IntPropLevel i) - : Base("Int::"+s), arity(a), dom(d), + : Base("Int::"+s, tags), arity(a), dom(d), reified(r), rms((1 << Gecode::RM_EQV) | (1 << Gecode::RM_IMP) | (1 << Gecode::RM_PMI)), @@ -183,10 +189,16 @@ namespace Test { namespace Int { testsearch(true), testfix(true) {} inline - Test::Test(const std::string& p, const std::string& s, + Test::Test(const std::string& s, + int a, const Gecode::IntSet& d, bool r, + Gecode::IntPropLevel i) + : Test(TestTag::normal,s,a,d,r,i) {} + + inline + Test::Test(TestTags tags, const std::string& p, const std::string& s, int a, int min, int max, bool r, Gecode::IntPropLevel i) - : Base(p+s), arity(a), dom(min,max), + : Base(p+s, tags), arity(a), dom(min,max), reified(r), rms((1 << Gecode::RM_EQV) | (1 << Gecode::RM_IMP) | (1 << Gecode::RM_PMI)), @@ -194,15 +206,26 @@ namespace Test { namespace Int { testsearch(true), testfix(true) {} inline - Test::Test(const std::string& s, + Test::Test(const std::string& p, const std::string& s, + int a, int min, int max, bool r, + Gecode::IntPropLevel i) + : Test(TestTag::normal,p,s,a,min,max,r,i) {} + + inline + Test::Test(TestTags tags, const std::string& s, int a, int min, int max, bool r, Gecode::IntPropLevel i) - : Base("Int::"+s), arity(a), dom(min,max), + : Base("Int::"+s, tags), arity(a), dom(min,max), reified(r), rms((1 << Gecode::RM_EQV) | (1 << Gecode::RM_IMP) | (1 << Gecode::RM_PMI)), ipl(i), contest(ipl == Gecode::IPL_DOM ? CTL_DOMAIN : CTL_NONE), testsearch(true), testfix(true) {} + inline + Test::Test(const std::string& s, + int a, int min, int max, bool r, Gecode::IntPropLevel i) + : Test(TestTag::normal,s,a,min,max,r,i) {} + inline std::string Test::str(Gecode::IntPropLevel ipl) { @@ -359,4 +382,3 @@ namespace Test { namespace Int { }} // STATISTICS: test-int - diff --git a/test/int/arithmetic.cpp b/test/int/arithmetic.cpp index 9146fef7bd..5e57a58933 100644 --- a/test/int/arithmetic.cpp +++ b/test/int/arithmetic.cpp @@ -2184,7 +2184,8 @@ namespace Test { namespace Int { /// Create and register test PowXY(const std::string& s, int n0, const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test("Arithmetic::Pow::XY::"+str(n0)+"::"+str(ipl)+"::"+s, + : Test(TestTag::sweep, + "Arithmetic::Pow::XY::"+str(n0)+"::"+str(ipl)+"::"+s, 2,d,false,ipl), n(n0) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -2216,7 +2217,9 @@ namespace Test { namespace Int { /// Create and register test PowXX(const std::string& s, int n0, const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test("Arithmetic::Pow::XX::"+str(n0)+"::"+str(ipl)+"::"+s, + : Test((n0 == 0) && (ipl == Gecode::IPL_BND) && (s == "A") + ? TestTag::normal : TestTag::sweep, + "Arithmetic::Pow::XX::"+str(n0)+"::"+str(ipl)+"::"+s, 1,d,false,ipl), n(n0) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -2300,7 +2303,8 @@ namespace Test { namespace Int { /// Create and register test NrootXY(const std::string& s, int n0, const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test("Arithmetic::Nroot::XY::"+str(n0)+"::"+str(ipl)+"::"+s, + : Test(TestTag::sweep, + "Arithmetic::Nroot::XY::"+str(n0)+"::"+str(ipl)+"::"+s, 2,d,false,ipl), n(n0) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -2330,7 +2334,9 @@ namespace Test { namespace Int { /// Create and register test NrootXX(const std::string& s, int n0, const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test("Arithmetic::Nroot::XX::"+str(n0)+"::"+str(ipl)+"::"+s, + : Test((n0 == 1) && (ipl == Gecode::IPL_BND) && (s == "A") + ? TestTag::normal : TestTag::sweep, + "Arithmetic::Nroot::XX::"+str(n0)+"::"+str(ipl)+"::"+s, 1,d,false,ipl), n(n0) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -2423,7 +2429,9 @@ namespace Test { namespace Int { /// Create and register test AbsXY(const std::string& s, const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test("Arithmetic::Abs::XY::"+str(ipl)+"::"+s,2,d,false,ipl) {} + : Test("Arithmetic::Abs::XY::"+str(ipl)+"::"+s,2,d,false,ipl) { + add_tags(TestTag::check); + } /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { double d0 = static_cast(x[0]); @@ -2442,7 +2450,9 @@ namespace Test { namespace Int { /// Create and register test AbsXX(const std::string& s, const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test("Arithmetic::Abs::XX::"+str(ipl)+"::"+s,1,d,false,ipl) {} + : Test("Arithmetic::Abs::XX::"+str(ipl)+"::"+s,1,d,false,ipl) { + add_tags(TestTag::check); + } /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { double d0 = static_cast(x[0]); @@ -2668,7 +2678,9 @@ namespace Test { namespace Int { public: /// Create and register test MaxNary(Gecode::IntPropLevel ipl) - : Test("Arithmetic::Max::Nary::"+str(ipl),4,-4,4,false,ipl) {} + : Test("Arithmetic::Max::Nary::"+str(ipl),4,-4,4,false,ipl) { + add_tags(TestTag::check); + } /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { return std::max(std::max(x[0],x[1]), x[2]) == x[3]; @@ -2686,7 +2698,9 @@ namespace Test { namespace Int { public: /// Create and register test MaxNaryShared(Gecode::IntPropLevel ipl) - : Test("Arithmetic::Max::Nary::Shared::"+str(ipl),3,-4,4,false,ipl) {} + : Test("Arithmetic::Max::Nary::Shared::"+str(ipl),3,-4,4,false,ipl) { + add_tags(TestTag::check); + } /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { return std::max(std::max(x[0],x[1]), x[2]) == x[1]; @@ -2712,7 +2726,9 @@ namespace Test { namespace Int { : Test("Arithmetic::ArgMax::"+str(o)+"::"+str(tb)+"::"+str(n), n+1,0,n+1, false,tb ? Gecode::IPL_DEF : Gecode::IPL_DOM), - offset(o), tiebreak(tb) {} + offset(o), tiebreak(tb) { + add_tags(TestTag::check); + } /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { int n=x.size()-1; @@ -2746,6 +2762,7 @@ namespace Test { namespace Int { : Test("Arithmetic::ArgMax::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1, false), tiebreak(tb) { + add_tags(TestTag::check); testfix=false; } /// %Test whether \a x is solution @@ -2860,7 +2877,9 @@ namespace Test { namespace Int { : Test("Arithmetic::ArgMaxBool::"+str(o)+"::"+str(tb)+"::"+str(n), n+1,0,n+1, false,tb ? Gecode::IPL_DEF : Gecode::IPL_DOM), - offset(o), tiebreak(tb) {} + offset(o), tiebreak(tb) { + add_tags(TestTag::check); + } /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { int n=x.size()-1; @@ -2899,6 +2918,7 @@ namespace Test { namespace Int { : Test("Arithmetic::ArgMaxBool::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1, false), tiebreak(tb) { + add_tags(TestTag::check); testfix=false; } /// %Test whether \a x is solution diff --git a/test/int/channel.cpp b/test/int/channel.cpp index 0a72f258ca..e1f4e12b3e 100644 --- a/test/int/channel.cpp +++ b/test/int/channel.cpp @@ -53,7 +53,7 @@ namespace Test { namespace Int { public: /// Construct and register test ChannelFull(int xoff0, int yoff0, Gecode::IntPropLevel ipl) - : Test("Channel::Full::"+str(xoff0)+"::"+str(yoff0)+"::"+str(ipl), + : Test(TestTag::sweep,"Channel::Full::"+str(xoff0)+"::"+str(yoff0)+"::"+str(ipl), 8,0,3,false,ipl), xoff(xoff0), yoff(yoff0) { contest = CTL_NONE; @@ -94,7 +94,7 @@ namespace Test { namespace Int { public: /// Construct and register test ChannelHalf(Gecode::IntPropLevel ipl) - : Test("Channel::Half::"+str(ipl),6,0,5,false,ipl) { + : Test(TestTag::sweep,"Channel::Half::"+str(ipl),6,0,5,false,ipl) { contest = CTL_NONE; } /// Check whether \a x is solution @@ -124,7 +124,7 @@ namespace Test { namespace Int { public: /// Construct and register test ChannelShared(Gecode::IntPropLevel ipl) - : Test("Channel::Shared::"+str(ipl),6,0,5,false,ipl) { + : Test(TestTag::sweep,"Channel::Shared::"+str(ipl),6,0,5,false,ipl) { contest = CTL_NONE; } /// Check whether \a x is solution @@ -146,7 +146,7 @@ namespace Test { namespace Int { public: /// Construct and register test ChannelLinkSingle(void) - : Test("Channel::Bool::Single",2,-1,2) { + : Test(TestTag::sweep,"Channel::Bool::Single",2,-1,2) { contest = CTL_NONE; } /// Check whether \a x is solution @@ -169,7 +169,8 @@ namespace Test { namespace Int { public: /// Construct and register test ChannelLinkMulti(const std::string& s, int min, int max, int o0) - : Test("Channel::Bool::Multi::"+s,7,min,max), o(o0) { + : Test(s == "A" ? TestTag::normal : TestTag::sweep, + "Channel::Bool::Multi::"+s,7,min,max), o(o0) { } /// Check whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -227,4 +228,3 @@ namespace Test { namespace Int { }} // STATISTICS: test-int - diff --git a/test/int/circuit.cpp b/test/int/circuit.cpp index 1eb0c14384..b274321a85 100644 --- a/test/int/circuit.cpp +++ b/test/int/circuit.cpp @@ -52,7 +52,7 @@ namespace Test { namespace Int { public: /// Create and register test Circuit(int n, int min, int max, int off, Gecode::IntPropLevel ipl) - : Test("Circuit::" + str(ipl) + "::" + str(n) + "::" + str(off), + : Test(TestTag::sweep,"Circuit::" + str(ipl) + "::" + str(n) + "::" + str(off), n,min,max,false,ipl), offset(off) { contest = CTL_NONE; testfix = false; @@ -95,7 +95,7 @@ namespace Test { namespace Int { public: /// Create and register test Path(int n, int min, int max, int off, Gecode::IntPropLevel ipl) - : Test("Path::" + str(ipl) + "::" + str(n) + "::" + str(off), + : Test(TestTag::sweep,"Path::" + str(ipl) + "::" + str(n) + "::" + str(off), n+2,min,max,false,ipl), offset(off) { contest = CTL_NONE; testfix = false; @@ -148,7 +148,9 @@ namespace Test { namespace Int { public: /// Create and register test CircuitCost(int n, int min, int max, int off, Gecode::IntPropLevel ipl) - : Test("Circuit::Cost::"+str(ipl)+"::"+str(n)+"::"+str(off), + : Test((ipl == Gecode::IPL_DOM) && (n == 4) && (off == 0) + ? TestTag::normal : TestTag::sweep, + "Circuit::Cost::"+str(ipl)+"::"+str(n)+"::"+str(off), n+1,min,max,false,ipl), offset(off) { contest = CTL_NONE; testfix = false; @@ -203,7 +205,9 @@ namespace Test { namespace Int { public: /// Create and register test PathCost(int n, int min, int max, int off, Gecode::IntPropLevel ipl) - : Test("Path::Cost::"+str(ipl)+"::"+str(n)+"::"+str(off), + : Test((ipl == Gecode::IPL_DOM) && (n == 3) && (off == 0) + ? TestTag::normal : TestTag::sweep, + "Path::Cost::"+str(ipl)+"::"+str(n)+"::"+str(off), n+3,min,max,false,ipl), offset(off) { contest = CTL_NONE; testfix = false; @@ -266,7 +270,7 @@ namespace Test { namespace Int { /// Create and register test CircuitFullCost(int n, int min, int max, int off, Gecode::IntPropLevel ipl) - : Test("Circuit::FullCost::" + str(ipl)+"::"+str(n)+"::"+str(off), + : Test(TestTag::sweep,"Circuit::FullCost::" + str(ipl)+"::"+str(n)+"::"+str(off), 2*n+1,min,max,false,ipl), offset(off) { contest = CTL_NONE; testfix = false; diff --git a/test/int/cumulative.cpp b/test/int/cumulative.cpp index e03c775883..8643c45221 100755 --- a/test/int/cumulative.cpp +++ b/test/int/cumulative.cpp @@ -76,10 +76,14 @@ namespace Test { namespace Int { const Gecode::IntArgs& u0, int o0, Gecode::IntPropLevel ipl0) - : Test("Cumulative::Man::Fix::"+str(o0)+"::"+ + : Test(TestTag::sweep,"Cumulative::Man::Fix::"+str(o0)+"::"+ str(c0)+"::"+str(p0)+"::"+str(u0)+"::"+str(ipl0), (c0 >= 0) ? p0.size():p0.size()+1,0,st(c0,p0,u0),false,ipl0), c(c0), p(p0), u(u0), o(o0) { + if ((o0 == 0) && (c0 == 4)) { + tags(TestTag::normal); + add_tags(TestTag::check); + } testsearch = false; testfix = false; contest = CTL_NONE; @@ -179,11 +183,13 @@ namespace Test { namespace Int { const Gecode::IntArgs& u0, int o0, Gecode::IntPropLevel ipl0) - : Test("Cumulative::Opt::Fix::"+str(o0)+"::"+ + : Test(TestTag::sweep,"Cumulative::Opt::Fix::"+str(o0)+"::"+ str(c0)+"::"+str(p0)+"::"+str(u0)+"::"+str(ipl0), (c0 >= 0) ? 2*p0.size() : 2*p0.size()+1,0,st(c0,p0,u0), false,ipl0), c(c0), p(p0), u(u0), l(st(c,p,u)/2), o(o0) { + if ((o0 == Gecode::Int::Limits::min) && (c0 == -1)) + tags(TestTag::normal); testsearch = false; testfix = false; contest = CTL_NONE; @@ -285,7 +291,7 @@ namespace Test { namespace Int { const Gecode::IntArgs& u0, int o0, Gecode::IntPropLevel ipl0) - : Test("Cumulative::Man::Flex::"+str(o0)+"::"+ + : Test(TestTag::sweep,"Cumulative::Man::Flex::"+str(o0)+"::"+ str(c0)+"::"+str(minP)+"::"+str(maxP)+"::"+str(u0)+ "::"+str(ipl0), (c0 >= 0) ? 2*u0.size() : 2*u0.size()+1, @@ -398,13 +404,16 @@ namespace Test { namespace Int { const Gecode::IntArgs& u0, int o0, Gecode::IntPropLevel ipl0) - : Test("Cumulative::Opt::Flex::"+str(o0)+"::"+ + : Test(TestTag::sweep,"Cumulative::Opt::Flex::"+str(o0)+"::"+ str(c0)+"::"+str(minP)+"::"+str(maxP)+"::"+str(u0)+ "::"+str(ipl0), (c0 >= 0) ? 3*u0.size() : 3*u0.size()+1, 0,std::max(maxP,st(c0,maxP,u0)), false,ipl0), c(c0), _minP(minP), _maxP(maxP), u(u0), l(std::max(maxP,st(c0,maxP,u0))/2), o(o0) { + if ((o0 == Gecode::Int::Limits::min) && (c0 == 4) && + (minP == 0) && (maxP == 2)) + tags(TestTag::normal); testsearch = false; testfix = false; contest = CTL_NONE; diff --git a/test/int/distinct.cpp b/test/int/distinct.cpp index c652f739b7..f4f8582104 100755 --- a/test/int/distinct.cpp +++ b/test/int/distinct.cpp @@ -53,11 +53,15 @@ namespace Test { namespace Int { /// Create and register test Distinct(const Gecode::IntSet& d0, Gecode::IntPropLevel ipl, int n=6) - : Test(std::string(useCount ? "Count::Distinct::" : "Distinct::")+ + : Test((useCount || (ipl != Gecode::IPL_VAL)) + ? TestTag::sweep : TestTag::normal, + std::string(useCount ? "Count::Distinct::" : "Distinct::")+ str(ipl)+"::Sparse::"+str(n),n,d0,false,ipl) {} /// Create and register test Distinct(int min, int max, Gecode::IntPropLevel ipl) - : Test(std::string(useCount ? "Count::Distinct::" : "Distinct::")+ + : Test((!useCount || (ipl == Gecode::IPL_BND)) + ? TestTag::normal : TestTag::sweep, + std::string(useCount ? "Count::Distinct::" : "Distinct::")+ str(ipl)+"::Dense",6,min,max,false,ipl) {} /// Check whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -87,10 +91,12 @@ namespace Test { namespace Int { public: /// Create and register test Offset(const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test("Distinct::Offset::Sparse::"+str(ipl),6,d,false,ipl) {} + : Test(TestTag::sweep, + "Distinct::Offset::Sparse::"+str(ipl),6,d,false,ipl) {} /// Create and register test Offset(int min, int max, Gecode::IntPropLevel ipl) - : Test("Distinct::Offset::Dense::"+str(ipl),6,min,max,false,ipl) {} + : Test(ipl == Gecode::IPL_BND ? TestTag::normal : TestTag::sweep, + "Distinct::Offset::Dense::"+str(ipl),6,min,max,false,ipl) {} /// Check whether \a x is solution virtual bool solution(const Assignment& x) const { for (int i=0; i> 1; @@ -443,7 +443,7 @@ namespace Test { namespace Int { public: /// Create and register test IntArrayInt(Gecode::IntRelType irt0) - : Test("Rel::Int::Array::Int::"+str(irt0),3,-2,2), irt(irt0) {} + : Test(TestTag::sweep,"Rel::Int::Array::Int::"+str(irt0),3,-2,2), irt(irt0) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { Gecode::IntArgs y({0,0,0}); @@ -476,7 +476,9 @@ namespace Test { namespace Int { public: /// Create and register test IntArrayDiff(Gecode::IntRelType irt0, int m) - : Test("Rel::Int::Array::"+str(irt0)+"::"+str(m)+"::"+str(n-m), + : Test((irt0 == Gecode::IRT_EQ) && (m == 0) + ? TestTag::normal : TestTag::sweep, + "Rel::Int::Array::"+str(irt0)+"::"+str(m)+"::"+str(n-m), n,-2,2), irt(irt0), n_fst(m) { assert(n_fst <= n); diff --git a/test/int/unary.cpp b/test/int/unary.cpp index 44abfc0e61..944dd9d105 100755 --- a/test/int/unary.cpp +++ b/test/int/unary.cpp @@ -62,9 +62,13 @@ namespace Test { namespace Int { namespace Unary { public: /// Create and register test ManFixPUnary(const Gecode::IntArgs& p0, int o, Gecode::IntPropLevel ipl0) - : Test("Unary::Man::Fix::"+str(o)+"::"+str(p0)+"::"+str(ipl0), + : Test(TestTag::sweep,"Unary::Man::Fix::"+str(o)+"::"+str(p0)+"::"+str(ipl0), p0.size(),o,o+st(p0),false,ipl0), p(p0) { + if ((o == Gecode::Int::Limits::min) && + (str(p0) == "[2,2,0,2,2]") && + (ipl0 == Gecode::IPL_ADVANCED)) + tags(TestTag::normal); testsearch = false; contest = CTL_NONE; } @@ -103,8 +107,12 @@ namespace Test { namespace Int { namespace Unary { public: /// Create and register test OptFixPUnary(const Gecode::IntArgs& p0, int o, Gecode::IntPropLevel ipl0) - : Test("Unary::Opt::Fix::"+str(o)+"::"+str(p0)+"::"+str(ipl0), + : Test(TestTag::sweep,"Unary::Opt::Fix::"+str(o)+"::"+str(p0)+"::"+str(ipl0), 2*p0.size(),o,o+st(p0),false,ipl0), p(p0), l(o+st(p)/2) { + if ((o == Gecode::Int::Limits::min) && + (str(p0) == "[2,2,0,2,2]") && + (ipl0 == Gecode::IPL_ADVANCED)) + tags(TestTag::normal); testsearch = false; contest = CTL_NONE; } @@ -148,9 +156,12 @@ namespace Test { namespace Int { namespace Unary { public: /// Create and register test ManFlexUnary(int n, int minP, int maxP, int o, Gecode::IntPropLevel ipl0) - : Test("Unary::Man::Flex::"+str(o)+"::"+str(n)+"::" + : Test(TestTag::sweep,"Unary::Man::Flex::"+str(o)+"::"+str(n)+"::" +str(minP)+"::"+str(maxP)+"::"+str(ipl0), 2*n,0,n*maxP,false,ipl0), _minP(minP), _maxP(maxP), off(o) { + if ((o == Gecode::Int::Limits::min) && (n == 4) && + (minP == 0) && (maxP == 2) && (ipl0 == Gecode::IPL_ADVANCED)) + tags(TestTag::normal); testsearch = false; testfix = false; contest = CTL_NONE; @@ -207,10 +218,13 @@ namespace Test { namespace Int { namespace Unary { public: /// Create and register test OptFlexUnary(int n, int minP, int maxP, int o, Gecode::IntPropLevel ipl0) - : Test("Unary::Opt::Flex::"+str(o)+"::"+str(n)+"::" + : Test(TestTag::sweep,"Unary::Opt::Flex::"+str(o)+"::"+str(n)+"::" +str(minP)+"::"+str(maxP)+"::"+str(ipl0), 3*n,0,n*maxP,false,ipl0), _minP(minP), _maxP(maxP), off(o), l(n*maxP/2) { + if ((o == Gecode::Int::Limits::min) && (n == 4) && + (minP == 0) && (maxP == 2) && (ipl0 == Gecode::IPL_ADVANCED)) + tags(TestTag::normal); testsearch = false; testfix = false; contest = CTL_NONE; diff --git a/test/nogoods.cpp b/test/nogoods.cpp index dfcb7b35e8..14c52f5984 100644 --- a/test/nogoods.cpp +++ b/test/nogoods.cpp @@ -224,7 +224,10 @@ namespace Test { NoGoods(ValBranch vb0, unsigned int t0, bool a0, bool n0) : Base("NoGoods::"+Model::name()+"::"+Model::val(vb0)+"::"+str(t0)+ "::"+(a0 ? "+" : "-")+"::"+(n0 ? "+" : "-")), - vb(vb0), t(t0), a(a0), n(n0) {} + vb(vb0), t(t0), a(a0), n(n0) { + if (Model::name() == "Queens") + add_tags(TestTag::check); + } /// Run test virtual bool run(void) { Model* m = new Model(vb,a,n); diff --git a/test/search.cpp b/test/search.cpp index 05f6d76547..2898150f96 100644 --- a/test/search.cpp +++ b/test/search.cpp @@ -759,7 +759,17 @@ namespace Test { : Test("DFS::"+Model::name()+"::"+ str(htb1)+"::"+str(htb2)+"::"+str(htb3)+"::"+ str(c_d0)+"::"+str(a_d0)+"::"+str(t0), - htb1,htb2,htb3), c_d(c_d0), a_d(a_d0), t(t0) {} + htb1,htb2,htb3), c_d(c_d0), a_d(a_d0), t(t0) { + if (Model::name().compare(0,3,"Sol") == 0) + tags(TestTag::sweep); + if ((Model::name() == "Sol") && + (htb1 == HTB_BINARY) && (htb2 == HTB_NARY) && + (htb3 == HTB_BINARY) && (c_d0 == 1) && + (a_d0 == 1) && (t0 == 1)) { + tags(TestTag::normal); + add_tags(TestTag::check); + } + } /// Run test virtual bool run(void) { Model* m = new Model(htb1,htb2,htb3); @@ -850,7 +860,15 @@ namespace Test { : Test("BAB::"+Model::name()+"::"+str(htc)+"::"+ str(htb1)+"::"+str(htb2)+"::"+str(htb3)+"::"+ str(c_d0)+"::"+str(a_d0)+"::"+str(t0), - htb1,htb2,htb3,htc), c_d(c_d0), a_d(a_d0), t(t0) {} + htb1,htb2,htb3,htc), c_d(c_d0), a_d(a_d0), t(t0) { + if (Model::name().compare(0,3,"Sol") == 0) + tags(TestTag::sweep); + if ((Model::name() == "Sol") && (htc == HTC_BAL_GR) && + (htb1 == HTB_BINARY) && (htb2 == HTB_BINARY) && + (htb3 == HTB_BINARY) && (c_d0 == 1) && + (a_d0 == 1) && (t0 == 1)) + tags(TestTag::normal); + } /// Run test virtual bool run(void) { Model* m = new Model(htb1,htb2,htb3,htc); diff --git a/test/set.hh b/test/set.hh index 8aae22c6f7..01cb0907ff 100644 --- a/test/set.hh +++ b/test/set.hh @@ -311,7 +311,11 @@ namespace Test { */ SetTest(const std::string& s, int a, const Gecode::IntSet& d, bool r=false, int w=0) - : Base("Set::"+s), arity(a), lub(d), reified(r), withInt(w), + : SetTest(TestTag::normal,s,a,d,r,w) {} + /// Construct and register a test with explicitly assigned tags + SetTest(TestTags tags, const std::string& s, + int a, const Gecode::IntSet& d, bool r=false, int w=0) + : Base("Set::"+s, tags), arity(a), lub(d), reified(r), withInt(w), disabled(true), testsubsumed(true) {} /// Check for solution virtual bool solution(const SetAssignment&) const = 0; diff --git a/test/set/channel.cpp b/test/set/channel.cpp index abed5619e0..cd4f32727a 100644 --- a/test/set/channel.cpp +++ b/test/set/channel.cpp @@ -63,7 +63,7 @@ namespace Test { namespace Set { public: /// Create and register test ChannelSorted(const char* t) - : SetTest(t,1,ds_33,false,3) {} + : SetTest(TestTag::sweep,t,1,ds_33,false,3) {} /// %Test whether \a x is solution virtual bool solution(const SetAssignment& x) const { if (x.ints()[0]>=x.ints()[1] || @@ -103,7 +103,7 @@ namespace Test { namespace Set { public: /// Create and register test ChannelInt(const char* t, const IntSet& d, int _ssize, int _isize) - : SetTest(t,_ssize,d,false,_isize), ssize(_ssize), isize(_isize) {} + : SetTest(TestTag::sweep,t,_ssize,d,false,_isize), ssize(_ssize), isize(_isize) {} /// %Test whether \a x is solution virtual bool solution(const SetAssignment& x) const { for (int i=0; i 2) @@ -319,7 +319,7 @@ namespace Test { namespace Set { public: /// Create and register test ElementSetConst(const char* t) - : SetTest(t,1,ds_13,false,true), i0(-3,-3), i1(-1,1), i2(0,2) {} + : SetTest(TestTag::sweep,t,1,ds_13,false,true), i0(-3,-3), i1(-1,1), i2(0,2) {} /// %Test whether \a x is solution virtual bool solution(const SetAssignment& x) const { if (x.intval() < 0 || x.intval() > 2) @@ -346,7 +346,7 @@ namespace Test { namespace Set { public: /// Create and register test MatrixIntSet(void) - : SetTest("Element::Matrix::IntSet",1,IntSet(0,3),false,2), + : SetTest(TestTag::sweep,"Element::Matrix::IntSet",1,IntSet(0,3),false,2), tm(4) { tm[0]=IntSet(0,0); tm[1]=IntSet(1,1); tm[2]=IntSet(2,2); tm[3]=IntSet(3,3); diff --git a/test/set/exec.cpp b/test/set/exec.cpp index 8bf911b4f4..2f123d4603 100644 --- a/test/set/exec.cpp +++ b/test/set/exec.cpp @@ -53,7 +53,9 @@ namespace Test { namespace Set { Wait(int n, bool sf0) : SetTest("Wait::"+str(n)+"::"+ (sf0 ? "std::function" : "funptr"),n, - Gecode::IntSet(0,n),false), sf(sf0) {} + Gecode::IntSet(0,n),false), sf(sf0) { + add_tags(TestTag::check); + } /// Check whether \a x is solution virtual bool solution(const SetAssignment& x) const { (void) x; diff --git a/test/set/mm-set.cpp b/test/set/mm-set.cpp index 6c7d83f7da..f031a8df8f 100755 --- a/test/set/mm-set.cpp +++ b/test/set/mm-set.cpp @@ -126,7 +126,9 @@ namespace Test { namespace Int { /// Create and register test SetExprConst(const SetInstr* bis0, const std::string& s, Gecode::SetRelType srt0, int c0) - : Test("MiniModel::SetExpr::Const::"+s+"::"+str(srt0)+"::"+str(c0), + : Test((s == "000") && (srt0 == Gecode::SRT_EQ) && (c0 == 0) + ? TestTag::normal : TestTag::sweep, + "MiniModel::SetExpr::Const::"+s+"::"+str(srt0)+"::"+str(c0), 4,0,1,simpleReifiedSemantics(bis0)), bis(bis0), c(c0), srt(srt0) {} /// %Test whether \a x is solution @@ -212,7 +214,9 @@ namespace Test { namespace Int { /// Create and register test SetExprExpr(const SetInstr* bis00, const SetInstr* bis10, const std::string& s, Gecode::SetRelType srt0) - : Test("MiniModel::SetExpr::Expr::"+s+"::"+str(srt0), + : Test((s == "000::000") && (srt0 == Gecode::SRT_EQ) + ? TestTag::normal : TestTag::sweep, + "MiniModel::SetExpr::Expr::"+s+"::"+str(srt0), 8,0,1, simpleReifiedSemantics(bis00) && simpleReifiedSemantics(bis10)), diff --git a/test/set/precede.cpp b/test/set/precede.cpp index b98988e63d..f9e2f746c1 100755 --- a/test/set/precede.cpp +++ b/test/set/precede.cpp @@ -64,7 +64,7 @@ namespace Test { namespace Set { public: /// Create and register test Single(int s0, int t0) - : SetTest("Precede::Single::"+str(s0)+"<"+str(t0),4,ds,false), + : SetTest(TestTag::sweep,"Precede::Single::"+str(s0)+"<"+str(t0),4,ds,false), s(s0), t(t0) {} /// %Test whether \a x is solution virtual bool solution(const SetAssignment& x) const { @@ -99,7 +99,9 @@ namespace Test { namespace Set { public: /// Create and register test Multi(const Gecode::IntArgs& c0) - : SetTest("Precede::Multi::"+str(c0),4,ds,false), c(c0) {} + : SetTest(str(c0) == "[1,2,3]" + ? TestTag::normal : TestTag::sweep, + "Precede::Multi::"+str(c0),4,ds,false), c(c0) {} /// %Test whether \a x is solution virtual bool solution(const SetAssignment& x) const { for (int j=0; j @@ -45,7 +44,6 @@ main(int argc, char* argv[]) { #ifdef GECODE_HAS_MTRACE mtrace(); #endif - Test::apply_gecode_test_tags(); return Test::run_registered_tests(argc, argv); } diff --git a/test/test.hh b/test/test.hh index 33ad7375b4..c900b118be 100755 --- a/test/test.hh +++ b/test/test.hh @@ -113,6 +113,8 @@ namespace Test { TestTags(void); /// Initialize with tag \a t TestTags(TestTag t); + /// Initialize with tags \a t0 and \a t1 + TestTags(TestTag t0, TestTag t1); /// Return set with all known tags static TestTags all(void); /// Whether no tags are set @@ -204,6 +206,8 @@ namespace Test { const std::string& name(void) const; /// Return tags for test TestTags tags(void) const; + /// Replace tags assigned to test with \a t + void tags(TestTags t); /// Add tags \a t to test void add_tags(TestTags t); /// Remove tags \a t from test diff --git a/test/test.hpp b/test/test.hpp index 3ea1b9a6b1..2864a0be2b 100755 --- a/test/test.hpp +++ b/test/test.hpp @@ -46,6 +46,10 @@ namespace Test { inline TestTags::TestTags(TestTag t) : _mask(static_cast(t)) {} + inline + TestTags::TestTags(TestTag t0, TestTag t1) + : _mask(static_cast(t0) | + static_cast(t1)) {} inline bool TestTags::empty(void) const { return _mask == 0; @@ -87,6 +91,10 @@ namespace Test { return _tags; } inline void + Base::tags(TestTags t) { + _tags = t; + } + inline void Base::add_tags(TestTags t) { _tags.add(t); } From a48929110332bb1d669ab99d42dfbbf20a63775f Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Sun, 6 Sep 2026 14:53:43 +0200 Subject: [PATCH 09/23] Polish public test tag integration --- CMakeLists.txt | 6 ++---- changelog.in | 9 +++++++++ cmake/GecodeSources.cmake | 4 +--- test/public-runner-smoke.cpp | 6 +++--- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec012b79d3..4e3b7afc17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -814,9 +814,7 @@ ${CONFIG_OUT}") include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GecodeSources.cmake) if(GECODE_ENABLE_FAULT_INJECTION) list(APPEND GECODE_SUPPORT_SOURCES gecode/support/failpoint.cpp) - set(GECODE_FAULT_TEST_SOURCES - test/test-main.cpp - test/fault.cpp) + set(GECODE_FAULT_TEST_SOURCES ${GECODE_TEST_MAIN_SOURCE} test/fault.cpp) endif() # --------------------------------------------------------------------------- @@ -1463,7 +1461,7 @@ if(BUILD_TESTING) endif() if(GECODE_CAN_BUILD_TESTS) - add_executable(gecode-test EXCLUDE_FROM_ALL ${GECODE_TEST_MAIN_SOURCES} ${GECODE_TEST_SOURCES_SELECTED}) + add_executable(gecode-test EXCLUDE_FROM_ALL ${GECODE_TEST_MAIN_SOURCE} ${GECODE_TEST_SOURCES_SELECTED}) set(GECODE_TEST_LINK_LIBS gecodeminimodel) if(TARGET gecodetestset) list(APPEND GECODE_TEST_LINK_LIBS gecodetestset) diff --git a/changelog.in b/changelog.in index b5a674bf27..38c76574ff 100755 --- a/changelog.in +++ b/changelog.in @@ -129,6 +129,15 @@ The factories retain nondeterminism without determinization or minimization; epsilon transitions are not supported. Regular propagation now preserves branching assigned prefixes when cloning such automata. +[ENTRY] +Module: test +What: new +Rank: major +[DESCRIPTION] +Add self-declared check, normal, and sweep tags to the public test harness. +The standard check targets use a focused integrity selection, while normal +testing retains broad coverage without the exhaustive multi-hour sweeps. + [ENTRY] Module: test What: new diff --git a/cmake/GecodeSources.cmake b/cmake/GecodeSources.cmake index 9201998b3b..eb013c2682 100644 --- a/cmake/GecodeSources.cmake +++ b/cmake/GecodeSources.cmake @@ -261,9 +261,7 @@ set(GECODE_TEST_FLOAT_SOURCES test/float.cpp ) -set(GECODE_TEST_MAIN_SOURCES - test/test-main.cpp -) +set(GECODE_TEST_MAIN_SOURCE test/test-main.cpp) set(GECODE_TEST_PUBLIC_RUNNER_SMOKE_SOURCE test/public-runner-smoke.cpp) set(GECODE_TEST_PUBLIC_INT_SMOKE_SOURCE test/public-int-smoke.cpp) set(GECODE_TEST_PUBLIC_SET_SMOKE_SOURCE test/public-set-smoke.cpp) diff --git a/test/public-runner-smoke.cpp b/test/public-runner-smoke.cpp index 3550668a6e..1a8110588b 100644 --- a/test/public-runner-smoke.cpp +++ b/test/public-runner-smoke.cpp @@ -48,7 +48,7 @@ namespace { class PassingSmokeTest : public Test::Base { public: PassingSmokeTest(void) - : Test::Base("Int::Linear::Int::Smoke::A-Pass") {} + : Test::Base("Smoke::A-Pass") {} bool run(void) override { passing_runs++; @@ -117,7 +117,7 @@ main(void) { "-list should succeed")) { return EXIT_FAILURE; } - const std::string pass_name = "Int::Linear::Int::Smoke::A-Pass"; + const std::string pass_name = "Smoke::A-Pass"; const std::string fail_name = "Smoke::B-Fail"; const std::size_t pass_pos = list_output.find(pass_name); const std::size_t fail_pos = list_output.find(fail_name); @@ -168,7 +168,7 @@ main(void) { } std::string pass_output; - if (!require(run_and_capture({"public-runner-smoke", "-test", "Int::Linear::Int::Smoke::A-Pass", "-iter", "1", "-stop", "true"}, + if (!require(run_and_capture({"public-runner-smoke", "-test", "Smoke::A-Pass", "-iter", "1", "-stop", "true"}, pass_output) == EXIT_SUCCESS, "filtered passing run should succeed")) { return EXIT_FAILURE; From fe085746e592db1bb5e50370b0c61de0b1a9602e Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Sun, 6 Sep 2026 15:24:52 +0200 Subject: [PATCH 10/23] Make non-default test tags explicit --- docs/cmake-build.md | 8 +- test/branch.cpp | 7 +- test/branch.hh | 3 + test/branch/set.cpp | 10 +- test/flatzinc.cpp | 5 +- test/flatzinc/blackbox.cpp | 6 +- test/float/arithmetic.cpp | 174 +++++++++++++++++----------------- test/float/linear.cpp | 60 ++++++------ test/float/mm-lin.cpp | 8 +- test/float/transcendental.cpp | 51 +++++----- test/float/trigonometric.cpp | 78 ++++++++------- test/int/arithmetic.cpp | 79 ++++++++------- test/int/channel.cpp | 12 +-- test/int/cumulative.cpp | 23 +++-- test/int/distinct.cpp | 4 +- test/int/extensional.cpp | 59 ++++++------ test/int/linear.cpp | 61 ++++++------ test/int/mm-lin.cpp | 13 +-- test/int/no-overlap.cpp | 19 ++-- test/int/nvalues.cpp | 25 +++-- test/int/unary.cpp | 136 +++++++++++++------------- test/nogoods.cpp | 31 +++--- test/search.cpp | 75 ++++++++------- test/set/channel.cpp | 13 ++- test/set/dom.cpp | 9 +- test/set/exec.cpp | 7 +- test/set/mm-set.cpp | 54 ++++++----- test/set/precede.cpp | 12 +-- test/set/rel-op-const.cpp | 8 +- test/set/sequence.cpp | 7 +- test/test.hh | 6 -- test/test.hpp | 12 --- 32 files changed, 539 insertions(+), 536 deletions(-) diff --git a/docs/cmake-build.md b/docs/cmake-build.md index 5c699ac089..95fc142e7f 100644 --- a/docs/cmake-build.md +++ b/docs/cmake-build.md @@ -98,10 +98,16 @@ gecode-test -tag check gecode-test -tag normal gecode-test -tag sweep gecode-test -tag normal -tag sweep +gecode-test -tag all ``` +With no `-tag` option, the runner does not restrict tests by tag. Repeated tags +form a union, while tag and name filters intersect. `-tag all` explicitly +selects every known tag. + Use `gecode-test -list-tags` to list known tags and -`gecode-test -list-with-tags` to inspect test assignments. +`gecode-test -list-with-tags` to inspect test assignments. Listing always shows +all registered tests, regardless of selection filters. ## Build Conventions and Key Options diff --git a/test/branch.cpp b/test/branch.cpp index 3010055a11..23a63bc86f 100644 --- a/test/branch.cpp +++ b/test/branch.cpp @@ -732,8 +732,13 @@ namespace Test { namespace Branch { } #ifdef GECODE_HAS_SET_VARS + SetTest::SetTest(TestTags tags, const std::string& s, int a, + const Gecode::IntSet& d) + : Base("Set::Branch::"+s,tags), arity(a), dom(d) { + } + SetTest::SetTest(const std::string& s, int a, const Gecode::IntSet& d) - : Base("Set::Branch::"+s), arity(a), dom(d) { + : SetTest(TestTag::normal,s,a,d) { } bool diff --git a/test/branch.hh b/test/branch.hh index efda94bbe3..a73dfec1b5 100644 --- a/test/branch.hh +++ b/test/branch.hh @@ -107,6 +107,9 @@ namespace Test { /// Domain of variables Gecode::IntSet dom; public: + /// Construct and register test with explicitly assigned tags + SetTest(TestTags tags, const std::string& s, int a, + const Gecode::IntSet& d); /// Construct and register test SetTest(const std::string& s, int a, const Gecode::IntSet& d); /// Perform test diff --git a/test/branch/set.cpp b/test/branch/set.cpp index 401a6e6c68..de3494bc8f 100644 --- a/test/branch/set.cpp +++ b/test/branch/set.cpp @@ -41,10 +41,8 @@ namespace Test { namespace Branch { class Set : public SetTest { public: /// Create and register test - Set(const std::string& s, const Gecode::IntSet& d, int n) - : SetTest(s,n,d) { - tags(s == "Dense::3" ? TestTag::normal : TestTag::sweep); - } + Set(TestTags tags, const std::string& s, const Gecode::IntSet& d, int n) + : SetTest(tags,s,n,d) {} /// Post propagators on variables \a x virtual void post(Gecode::Space& home, Gecode::SetVarArray& x) { Gecode::SetVarArgs xx(x.size()-1); @@ -59,8 +57,8 @@ namespace Test { namespace Branch { const int v_sparse[6] = {-100,-10,0,10,100,1000}; Gecode::IntSet d_sparse(v_sparse,6); - Set d_3("Dense::3",d_dense,3); - Set s_3("Sparse::3",d_sparse,3); + Set d_3(TestTag::normal,"Dense::3",d_dense,3); + Set s_3(TestTag::sweep,"Sparse::3",d_sparse,3); } }} diff --git a/test/flatzinc.cpp b/test/flatzinc.cpp index 5417997651..ee98085d94 100755 --- a/test/flatzinc.cpp +++ b/test/flatzinc.cpp @@ -81,9 +81,8 @@ namespace Test { namespace FlatZinc { } public: GistStatisticsMode(void) - : Base("FlatZinc::Options::GistStatisticsMode") { - add_tags(TestTag::check); - } + : Base("FlatZinc::Options::GistStatisticsMode", + TestTags(TestTag::normal,TestTag::check)) {} virtual bool run(void) { return diff --git a/test/flatzinc/blackbox.cpp b/test/flatzinc/blackbox.cpp index 7a1d443f77..8cad3592ee 100644 --- a/test/flatzinc/blackbox.cpp +++ b/test/flatzinc/blackbox.cpp @@ -256,9 +256,9 @@ namespace Test { namespace FlatZinc { namespace Blackbox { class NativeProtocol : public Base { public: - NativeProtocol(void) : Base("FlatZinc::blackbox::native_protocol") { - add_tags(TestTag::check); - } + NativeProtocol(void) + : Base("FlatZinc::blackbox::native_protocol", + TestTags(TestTag::normal,TestTag::check)) {} virtual bool run(void) { std::vector int_input{-2}; std::vector float_input{1.25}; diff --git a/test/float/arithmetic.cpp b/test/float/arithmetic.cpp index d438b959c8..21c99a7f26 100755 --- a/test/float/arithmetic.cpp +++ b/test/float/arithmetic.cpp @@ -134,9 +134,8 @@ namespace Test { namespace Float { public: /// Create and register test PositiveNRootBounds(void) - : Base("Float::Arithmetic::PositiveNRootBounds") { - add_tags(TestTag::check); - } + : Base("Float::Arithmetic::PositiveNRootBounds", + TestTags(TestTag::normal,TestTag::check)) {} /// Run test under every supported IEEE-754 rounding mode virtual bool run(void) { const int oldMode = std::fegetround(); @@ -366,9 +365,9 @@ namespace Test { namespace Float { } public: /// Create and register test - PowConsistency(void) : Base("Float::Arithmetic::PowConsistency") { - add_tags(TestTag::check); - } + PowConsistency(void) + : Base("Float::Arithmetic::PowConsistency", + TestTags(TestTag::normal,TestTag::check)) {} /// Run zero and fixpoint regressions virtual bool run(void) { bool result = true; @@ -490,9 +489,8 @@ namespace Test { namespace Float { public: /// Create and register test MultZeroEndpoint(void) - : Base("Float::Arithmetic::MultZeroEndpoint") { - add_tags(TestTag::check); - } + : Base("Float::Arithmetic::MultZeroEndpoint", + TestTags(TestTag::normal,TestTag::check)) {} /// Run sign, symmetry, signed-zero, and zero-product cases virtual bool run(void) { bool result = true; @@ -549,13 +547,10 @@ namespace Test { namespace Float { class MultXYZSol : public Test { public: /// Create and register test - MultXYZSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Mult::XYZ::Sol::"+s,3,d,st,EXTEND_ASSIGNMENT,false) { - if (s == "C") { - tags(TestTag::normal); - add_tags(TestTag::check); - } - } + MultXYZSol(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, Gecode::FloatNum st) + : Test(tags,"Arithmetic::Mult::XYZ::Sol::"+s, + 3,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[1], x[2]); @@ -670,9 +665,10 @@ namespace Test { namespace Float { class Div : public Test { public: /// Create and register test - Div(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(s == "A" ? TestTag::normal : TestTag::sweep, - "Arithmetic::Div::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} + Div(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, Gecode::FloatNum st) + : Test(tags,"Arithmetic::Div::"+s, + 3,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] / x[1], x[2]); @@ -761,9 +757,10 @@ namespace Test { namespace Float { class SqrXX : public Test { public: /// Create and register test - SqrXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(s == "A" ? TestTag::normal : TestTag::sweep, - "Arithmetic::Sqr::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + SqrXX(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, Gecode::FloatNum st) + : Test(tags,"Arithmetic::Sqr::XX::"+s, + 1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[0], x[0]); @@ -833,9 +830,10 @@ namespace Test { namespace Float { class SqrtXX : public Test { public: /// Create and register test - SqrtXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(s == "A" ? TestTag::normal : TestTag::sweep, - "Arithmetic::Sqrt::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + SqrtXX(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, Gecode::FloatNum st) + : Test(tags,"Arithmetic::Sqrt::XX::"+s, + 1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { switch (cmp(x[0], Gecode::FRT_GQ, 0.0)) { @@ -876,13 +874,11 @@ namespace Test { namespace Float { unsigned int n; public: /// Create and register test - PowXYSol(const std::string& s, const Gecode::FloatVal& d, unsigned int _n, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Pow::N::"+str(_n)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), n(_n) { - if ((_n == 2) && (s == "C")) { - tags(TestTag::normal); - add_tags(TestTag::check); - } - } + PowXYSol(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, unsigned int _n, + Gecode::FloatNum st) + : Test(tags,"Arithmetic::Pow::N::"+str(_n)+"::XY::Sol::"+s, + 2,d,st,EXTEND_ASSIGNMENT,false), n(_n) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(pow(x[0],n), x[1]); @@ -947,13 +943,11 @@ namespace Test { namespace Float { unsigned int n; public: /// Create and register test - NRootXYSol(const std::string& s, const Gecode::FloatVal& d, unsigned int _n, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::NRoot::N::"+str(_n)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), n(_n) { - if ((_n == 2) && (s == "C")) { - tags(TestTag::normal); - add_tags(TestTag::check); - } - } + NRootXYSol(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, unsigned int _n, + Gecode::FloatNum st) + : Test(tags,"Arithmetic::NRoot::N::"+str(_n)+"::XY::Sol::"+s, + 2,d,st,EXTEND_ASSIGNMENT,false), n(_n) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((n == 0) || (x[0].min() < 0.0)) @@ -1020,9 +1014,10 @@ namespace Test { namespace Float { class AbsXX : public Test { public: /// Create and register test - AbsXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(s == "A" ? TestTag::normal : TestTag::sweep, - "Arithmetic::Abs::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + AbsXX(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, Gecode::FloatNum st) + : Test(tags,"Arithmetic::Abs::XX::"+s, + 1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(abs(x[0]), x[0]); @@ -1104,9 +1099,10 @@ namespace Test { namespace Float { class MinXXX : public Test { public: /// Create and register test - MinXXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(s == "A" ? TestTag::normal : TestTag::sweep, - "Arithmetic::Min::Bin::XXX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + MinXXX(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, Gecode::FloatNum st) + : Test(tags,"Arithmetic::Min::Bin::XXX::"+s, + 1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(x[0],x[0]), x[0]); @@ -1188,9 +1184,10 @@ namespace Test { namespace Float { class MaxXXX : public Test { public: /// Create and register test - MaxXXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(s == "A" ? TestTag::normal : TestTag::sweep, - "Arithmetic::Max::Bin::XXX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + MaxXXX(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, Gecode::FloatNum st) + : Test(tags,"Arithmetic::Max::Bin::XXX::"+s, + 1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(x[0],x[0]), x[0]); @@ -1308,13 +1305,14 @@ namespace Test { namespace Float { MultXYZ mult_xyz_b("B",b,step); MultXYZ mult_xyz_c("C",c,step); - MultXYZSol mult_xyz_sol_a("A",a,step); - MultXYZSol mult_xyz_sol_b("B",b,step); - MultXYZSol mult_xyz_sol_c("C",c,step); + MultXYZSol mult_xyz_sol_a(TestTag::sweep,"A",a,step); + MultXYZSol mult_xyz_sol_b(TestTag::sweep,"B",b,step); + MultXYZSol mult_xyz_sol_c( + TestTags(TestTag::normal,TestTag::check),"C",c,step); - Div div_a("A",a,step); - Div div_b("B",b,step); - Div div_c("C",c,step); + Div div_a(TestTag::normal,"A",a,step); + Div div_b(TestTag::sweep,"B",b,step); + Div div_c(TestTag::sweep,"C",c,step); DivSol div_sol_a("A",a,step); DivSol div_sol_b("B",b,step); @@ -1328,9 +1326,9 @@ namespace Test { namespace Float { SqrXYSol sqr_xy_sol_b("B",b,step); SqrXYSol sqr_xy_sol_c("C",c,step); - SqrXX sqr_xx_a("A",a,step); - SqrXX sqr_xx_b("B",b,step); - SqrXX sqr_xx_c("C",c,step); + SqrXX sqr_xx_a(TestTag::normal,"A",a,step); + SqrXX sqr_xx_b(TestTag::sweep,"B",b,step); + SqrXX sqr_xx_c(TestTag::sweep,"C",c,step); SqrtXY sqrt_xy_a("A",a,step); SqrtXY sqrt_xy_b("B",b,step); @@ -1340,17 +1338,18 @@ namespace Test { namespace Float { SqrtXYSol sqrt_xy_sol_b("B",b,step); SqrtXYSol sqrt_xy_sol_c("C",c,step); - SqrtXX sqrt_xx_a("A",a,step); - SqrtXX sqrt_xx_b("B",b,step); - SqrtXX sqrt_xx_c("C",c,step); + SqrtXX sqrt_xx_a(TestTag::normal,"A",a,step); + SqrtXX sqrt_xx_b(TestTag::sweep,"B",b,step); + SqrtXX sqrt_xx_c(TestTag::sweep,"C",c,step); PowXY pow_xy_a_1("A",a,2,step); PowXY pow_xy_b_1("B",b,2,step); PowXY pow_xy_c_1("C",c,2,step); - PowXYSol pow_xy_sol_a_1("A",a,2,step); - PowXYSol pow_xy_sol_b_1("B",b,2,step); - PowXYSol pow_xy_sol_c_1("C",c,2,step); + PowXYSol pow_xy_sol_a_1(TestTag::sweep,"A",a,2,step); + PowXYSol pow_xy_sol_b_1(TestTag::sweep,"B",b,2,step); + PowXYSol pow_xy_sol_c_1( + TestTags(TestTag::normal,TestTag::check),"C",c,2,step); PowXX pow_xx_a_1("A",a,2,step); PowXX pow_xx_b_1("B",b,2,step); @@ -1360,9 +1359,9 @@ namespace Test { namespace Float { PowXY pow_xy_b_2("B",b,3,step); PowXY pow_xy_c_2("C",c,3,step); - PowXYSol pow_xy_sol_a_2("A",a,3,step); - PowXYSol pow_xy_sol_b_2("B",b,3,step); - PowXYSol pow_xy_sol_c_2("C",c,3,step); + PowXYSol pow_xy_sol_a_2(TestTag::sweep,"A",a,3,step); + PowXYSol pow_xy_sol_b_2(TestTag::sweep,"B",b,3,step); + PowXYSol pow_xy_sol_c_2(TestTag::sweep,"C",c,3,step); PowXX pow_xx_a_2("A",a,3,step); PowXX pow_xx_b_2("B",b,3,step); @@ -1372,9 +1371,9 @@ namespace Test { namespace Float { PowXY pow_xy_b_3("B",b,0,step); PowXY pow_xy_c_3("C",c,0,step); - PowXYSol pow_xy_sol_a_3("A",a,0,step); - PowXYSol pow_xy_sol_b_3("B",b,0,step); - PowXYSol pow_xy_sol_c_3("C",c,0,step); + PowXYSol pow_xy_sol_a_3(TestTag::sweep,"A",a,0,step); + PowXYSol pow_xy_sol_b_3(TestTag::sweep,"B",b,0,step); + PowXYSol pow_xy_sol_c_3(TestTag::sweep,"C",c,0,step); PowXX pow_xx_a_3("A",a,0,step); PowXX pow_xx_b_3("B",b,0,step); @@ -1384,9 +1383,10 @@ namespace Test { namespace Float { NRootXY nroot_xy_b_1("B",b,2,step); NRootXY nroot_xy_c_1("C",c,2,step); - NRootXYSol nroot_xy_sol_a_1("A",a,2,step); - NRootXYSol nroot_xy_sol_b_1("B",b,2,step); - NRootXYSol nroot_xy_sol_c_1("C",c,2,step); + NRootXYSol nroot_xy_sol_a_1(TestTag::sweep,"A",a,2,step); + NRootXYSol nroot_xy_sol_b_1(TestTag::sweep,"B",b,2,step); + NRootXYSol nroot_xy_sol_c_1( + TestTags(TestTag::normal,TestTag::check),"C",c,2,step); NRootXX nroot_xx_a_1("A",a,2,step); NRootXX nroot_xx_b_1("B",b,2,step); @@ -1396,9 +1396,9 @@ namespace Test { namespace Float { NRootXY nroot_xy_b_2("B",b,3,step); NRootXY nroot_xy_c_2("C",c,3,step); - NRootXYSol nroot_xy_sol_a_2("A",a,3,step); - NRootXYSol nroot_xy_sol_b_2("B",b,3,step); - NRootXYSol nroot_xy_sol_c_2("C",c,3,step); + NRootXYSol nroot_xy_sol_a_2(TestTag::sweep,"A",a,3,step); + NRootXYSol nroot_xy_sol_b_2(TestTag::sweep,"B",b,3,step); + NRootXYSol nroot_xy_sol_c_2(TestTag::sweep,"C",c,3,step); NRootXX nroot_xx_a_2("A",a,3,step); NRootXX nroot_xx_b_2("B",b,3,step); @@ -1408,9 +1408,9 @@ namespace Test { namespace Float { NRootXY nroot_xy_b_3("B",b,0,step); NRootXY nroot_xy_c_3("C",c,0,step); - NRootXYSol nroot_xy_sol_a_3("A",a,0,step); - NRootXYSol nroot_xy_sol_b_3("B",b,0,step); - NRootXYSol nroot_xy_sol_c_3("C",c,0,step); + NRootXYSol nroot_xy_sol_a_3(TestTag::sweep,"A",a,0,step); + NRootXYSol nroot_xy_sol_b_3(TestTag::sweep,"B",b,0,step); + NRootXYSol nroot_xy_sol_c_3(TestTag::sweep,"C",c,0,step); NRootXX nroot_xx_a_3("A",a,0,step); NRootXX nroot_xx_b_3("B",b,0,step); @@ -1420,9 +1420,9 @@ namespace Test { namespace Float { AbsXY abs_xy_b("B",b,step); AbsXY abs_xy_c("C",c,step); - AbsXX abs_xx_a("A",a,step); - AbsXX abs_xx_b("B",b,step); - AbsXX abs_xx_c("C",c,step); + AbsXX abs_xx_a(TestTag::normal,"A",a,step); + AbsXX abs_xx_b(TestTag::sweep,"B",b,step); + AbsXX abs_xx_c(TestTag::sweep,"C",c,step); MinXYZ min_xyz_a("A",a,step); MinXYZ min_xyz_b("B",b,step); @@ -1440,9 +1440,9 @@ namespace Test { namespace Float { MinXYY min_xyy_b("B",b,step); MinXYY min_xyy_c("C",c,step); - MinXXX min_xxx_a("A",a,step); - MinXXX min_xxx_b("B",b,step); - MinXXX min_xxx_c("C",c,step); + MinXXX min_xxx_a(TestTag::normal,"A",a,step); + MinXXX min_xxx_b(TestTag::sweep,"B",b,step); + MinXXX min_xxx_c(TestTag::sweep,"C",c,step); MaxXYZ max_xyz_a("A",a,step); MaxXYZ max_xyz_b("B",b,step); @@ -1460,9 +1460,9 @@ namespace Test { namespace Float { MaxXYY max_xyy_b("B",b,step); MaxXYY max_xyy_c("C",c,step); - MaxXXX max_xxx_a("A",a,step); - MaxXXX max_xxx_b("B",b,step); - MaxXXX max_xxx_c("C",c,step); + MaxXXX max_xxx_a(TestTag::normal,"A",a,step); + MaxXXX max_xxx_b(TestTag::sweep,"B",b,step); + MaxXXX max_xxx_c(TestTag::sweep,"C",c,step); MinNary min_nary; MinNaryShared min_s_nary; diff --git a/test/float/linear.cpp b/test/float/linear.cpp index 8111250674..1796f1e6f6 100644 --- a/test/float/linear.cpp +++ b/test/float/linear.cpp @@ -66,12 +66,11 @@ namespace Test { namespace Float { Gecode::FloatNum c; public: /// Create and register test - FloatFloat(const std::string& s, const Gecode::FloatVal& d, + FloatFloat(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, const Gecode::FloatValArgs& a0, Gecode::FloatRelType frt0, Gecode::FloatNum c0, Gecode::FloatNum st) - : Test((s == "11") && (frt0 == Gecode::FRT_EQ) && - (c0 == 0.0) && (a0.size() == 1) - ? TestTag::normal : TestTag::sweep,"Linear::Float::"+ + : Test(tags,"Linear::Float::"+ str(frt0)+"::"+s+"::"+str(c0)+"::" +str(a0.size()), a0.size(),d,st,CPLT_ASSIGNMENT,true), @@ -130,11 +129,10 @@ namespace Test { namespace Float { Gecode::FloatRelType frt; public: /// Create and register test - FloatVar(const std::string& s, const Gecode::FloatVal& d, + FloatVar(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, const Gecode::FloatValArgs& a0, Gecode::FloatRelType frt0, Gecode::FloatNum st) - : Test((s == "11") && (frt0 == Gecode::FRT_EQ) && - (a0.size() == 1) ? TestTag::normal : TestTag::sweep, - "Linear::Var::"+ + : Test(tags,"Linear::Var::"+ str(frt0)+"::"+s+"::"+str(a0.size()), a0.size()+1,d,st,CPLT_ASSIGNMENT,true), a(a0), frt(frt0) { @@ -207,11 +205,13 @@ namespace Test { namespace Float { a1[0] = 0.0; for (FloatRelTypes frts; frts(); ++frts) { - (void) new FloatFloat("11",f1,a1,frts.frt(),0.0,step); - (void) new FloatVar("11",f1,a1,frts.frt(),step); - (void) new FloatFloat("21",f2,a1,frts.frt(),0.0,step); - (void) new FloatVar("21",f2,a1,frts.frt(),step); - (void) new FloatFloat("31",f3,a1,frts.frt(),1.0,step); + TestTags tags = frts.frt() == Gecode::FRT_EQ + ? TestTag::normal : TestTag::sweep; + (void) new FloatFloat(tags,"11",f1,a1,frts.frt(),0.0,step); + (void) new FloatVar(tags,"11",f1,a1,frts.frt(),step); + (void) new FloatFloat(TestTag::sweep,"21",f2,a1,frts.frt(),0.0,step); + (void) new FloatVar(TestTag::sweep,"21",f2,a1,frts.frt(),step); + (void) new FloatFloat(TestTag::sweep,"31",f3,a1,frts.frt(),1.0,step); } const FloatVal av2[4] = {1.0,1.0,1.0,1.0}; @@ -225,24 +225,24 @@ namespace Test { namespace Float { FloatValArgs a4(i, av4); FloatValArgs a5(i, av5); for (FloatRelTypes frts; frts(); ++frts) { - (void) new FloatFloat("12",f1,a2,frts.frt(),0.0,step); - (void) new FloatFloat("13",f1,a3,frts.frt(),0.0,step); - (void) new FloatFloat("14",f1,a4,frts.frt(),0.0,step); - (void) new FloatFloat("15",f1,a5,frts.frt(),0.0,step); - (void) new FloatFloat("22",f2,a2,frts.frt(),0.0,step); - (void) new FloatFloat("23",f2,a3,frts.frt(),0.0,step); - (void) new FloatFloat("24",f2,a4,frts.frt(),0.0,step); - (void) new FloatFloat("25",f2,a5,frts.frt(),0.0,step); - (void) new FloatFloat("32",f3,a2,frts.frt(),1.0,step); + (void) new FloatFloat(TestTag::sweep,"12",f1,a2,frts.frt(),0.0,step); + (void) new FloatFloat(TestTag::sweep,"13",f1,a3,frts.frt(),0.0,step); + (void) new FloatFloat(TestTag::sweep,"14",f1,a4,frts.frt(),0.0,step); + (void) new FloatFloat(TestTag::sweep,"15",f1,a5,frts.frt(),0.0,step); + (void) new FloatFloat(TestTag::sweep,"22",f2,a2,frts.frt(),0.0,step); + (void) new FloatFloat(TestTag::sweep,"23",f2,a3,frts.frt(),0.0,step); + (void) new FloatFloat(TestTag::sweep,"24",f2,a4,frts.frt(),0.0,step); + (void) new FloatFloat(TestTag::sweep,"25",f2,a5,frts.frt(),0.0,step); + (void) new FloatFloat(TestTag::sweep,"32",f3,a2,frts.frt(),1.0,step); if (i < 4) { - (void) new FloatVar("12",f1,a2,frts.frt(),step); - (void) new FloatVar("13",f1,a3,frts.frt(),step); - (void) new FloatVar("14",f1,a4,frts.frt(),step); - (void) new FloatVar("15",f1,a5,frts.frt(),step); - (void) new FloatVar("22",f2,a2,frts.frt(),step); - (void) new FloatVar("23",f2,a3,frts.frt(),step); - (void) new FloatVar("24",f2,a4,frts.frt(),step); - (void) new FloatVar("25",f2,a5,frts.frt(),step); + (void) new FloatVar(TestTag::sweep,"12",f1,a2,frts.frt(),step); + (void) new FloatVar(TestTag::sweep,"13",f1,a3,frts.frt(),step); + (void) new FloatVar(TestTag::sweep,"14",f1,a4,frts.frt(),step); + (void) new FloatVar(TestTag::sweep,"15",f1,a5,frts.frt(),step); + (void) new FloatVar(TestTag::sweep,"22",f2,a2,frts.frt(),step); + (void) new FloatVar(TestTag::sweep,"23",f2,a3,frts.frt(),step); + (void) new FloatVar(TestTag::sweep,"24",f2,a4,frts.frt(),step); + (void) new FloatVar(TestTag::sweep,"25",f2,a5,frts.frt(),step); } } } diff --git a/test/float/mm-lin.cpp b/test/float/mm-lin.cpp index 0168e67a0a..29857890dc 100644 --- a/test/float/mm-lin.cpp +++ b/test/float/mm-lin.cpp @@ -98,9 +98,8 @@ namespace Test { namespace Float { const LinInstr* lis; public: /// Create and register test - LinExpr(const LinInstr* lis0, const std::string& s) - : Test(s == "000" ? TestTag::normal : TestTag::sweep, - "Float::","MiniModel::LinExpr::"+s,4,-3,3), + LinExpr(TestTags tags, const LinInstr* lis0, const std::string& s) + : Test(tags,"Float::","MiniModel::LinExpr::"+s,4,-3,3), lis(lis0) { testfix = false; } @@ -1875,7 +1874,8 @@ namespace Test { namespace Float { } else if (i < 100) { s = "0" + s; } - (void) new LinExpr(li[i],s); + (void) new LinExpr(i == 0 ? TestTag::normal : TestTag::sweep, + li[i],s); } FloatRelTypes frts; for (int i=0; i 1.0) || (x[0].max() < -1.0)) @@ -357,9 +361,10 @@ namespace Test { namespace Float { class ACosXX : public Test { public: /// Create and register test - ACosXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(s == "A" ? TestTag::normal : TestTag::sweep, - "Trigonometric::ACos::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + ACosXX(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, Gecode::FloatNum st) + : Test(tags,"Trigonometric::ACos::XX::"+s, + 1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].min() > 1.0) || (x[0].max() < -1.0)) @@ -421,9 +426,10 @@ namespace Test { namespace Float { class ATanXX : public Test { public: /// Create and register test - ATanXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(s == "A" ? TestTag::normal : TestTag::sweep, - "Trigonometric::ATan::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + ATanXX(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, Gecode::FloatNum st) + : Test(tags,"Trigonometric::ATan::XX::"+s, + 1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(atan(x[0]), x[0]); @@ -448,9 +454,9 @@ namespace Test { namespace Float { SinXYSol sin_xy_sol_b("B",b,step); SinXYSol sin_xy_sol_c("C",c,step); - SinXX sin_xx_a("A",a,step); - SinXX sin_xx_b("B",b,step); - SinXX sin_xx_c("C",c,step); + SinXX sin_xx_a(TestTag::normal,"A",a,step); + SinXX sin_xx_b(TestTag::sweep,"B",b,step); + SinXX sin_xx_c(TestTag::sweep,"C",c,step); CosXY cos_xy_a("A",a,step); CosXY cos_xy_b("B",b,step); @@ -460,9 +466,9 @@ namespace Test { namespace Float { CosXYSol cos_xy_sol_b("B",b,step); CosXYSol cos_xy_sol_c("C",c,step); - CosXX cos_xx_a("A",a,step); - CosXX cos_xx_b("B",b,step); - CosXX cos_xx_c("C",c,step); + CosXX cos_xx_a(TestTag::normal,"A",a,step); + CosXX cos_xx_b(TestTag::sweep,"B",b,step); + CosXX cos_xx_c(TestTag::sweep,"C",c,step); TanXY tan_xy_a("A",a,step); TanXY tan_xy_b("B",b,step); @@ -472,9 +478,9 @@ namespace Test { namespace Float { TanXYSol tan_xy_sol_b("B",b,step); TanXYSol tan_xy_sol_c("C",c,step); - TanXX tan_xx_a("A",a,step); - TanXX tan_xx_b("B",b,step); - TanXX tan_xx_c("C",c,step); + TanXX tan_xx_a(TestTag::normal,"A",a,step); + TanXX tan_xx_b(TestTag::sweep,"B",b,step); + TanXX tan_xx_c(TestTag::sweep,"C",c,step); ASinXY asin_xy_a("A",a,step); ASinXY asin_xy_b("B",b,step); @@ -484,9 +490,9 @@ namespace Test { namespace Float { ASinXYSol asin_xy_sol_b("B",b,step); ASinXYSol asin_xy_sol_c("C",c,step); - ASinXX asin_xx_a("A",a,step); - ASinXX asin_xx_b("B",b,step); - ASinXX asin_xx_c("C",c,step); + ASinXX asin_xx_a(TestTag::normal,"A",a,step); + ASinXX asin_xx_b(TestTag::sweep,"B",b,step); + ASinXX asin_xx_c(TestTag::sweep,"C",c,step); ACosXY acos_xy_a("A",a,step); ACosXY acos_xy_b("B",b,step); @@ -496,9 +502,9 @@ namespace Test { namespace Float { ACosXYSol acos_xy_sol_b("B",b,step); ACosXYSol acos_xy_sol_c("C",c,step); - ACosXX acos_xx_a("A",a,step); - ACosXX acos_xx_b("B",b,step); - ACosXX acos_xx_c("C",c,step); + ACosXX acos_xx_a(TestTag::normal,"A",a,step); + ACosXX acos_xx_b(TestTag::sweep,"B",b,step); + ACosXX acos_xx_c(TestTag::sweep,"C",c,step); ATanXY atan_xy_a("A",a,step); ATanXY atan_xy_b("B",b,step); @@ -508,9 +514,9 @@ namespace Test { namespace Float { ATanXYSol atan_xy_sol_b("B",b,step); ATanXYSol atan_xy_sol_c("C",c,step); - ATanXX atan_xx_a("A",a,step); - ATanXX atan_xx_b("B",b,step); - ATanXX atan_xx_c("C",c,step); + ATanXX atan_xx_a(TestTag::normal,"A",a,step); + ATanXX atan_xx_b(TestTag::sweep,"B",b,step); + ATanXX atan_xx_c(TestTag::sweep,"C",c,step); //@} diff --git a/test/int/arithmetic.cpp b/test/int/arithmetic.cpp index 5e57a58933..d83eb87aec 100644 --- a/test/int/arithmetic.cpp +++ b/test/int/arithmetic.cpp @@ -2215,10 +2215,10 @@ namespace Test { namespace Int { int n; public: /// Create and register test - PowXX(const std::string& s, int n0, const Gecode::IntSet& d, + PowXX(TestTags tags, const std::string& s, + int n0, const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test((n0 == 0) && (ipl == Gecode::IPL_BND) && (s == "A") - ? TestTag::normal : TestTag::sweep, + : Test(tags, "Arithmetic::Pow::XX::"+str(n0)+"::"+str(ipl)+"::"+s, 1,d,false,ipl), n(n0) {} /// %Test whether \a x is solution @@ -2332,10 +2332,10 @@ namespace Test { namespace Int { int n; public: /// Create and register test - NrootXX(const std::string& s, int n0, const Gecode::IntSet& d, + NrootXX(TestTags tags, const std::string& s, + int n0, const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test((n0 == 1) && (ipl == Gecode::IPL_BND) && (s == "A") - ? TestTag::normal : TestTag::sweep, + : Test(tags, "Arithmetic::Nroot::XX::"+str(n0)+"::"+str(ipl)+"::"+s, 1,d,false,ipl), n(n0) {} /// %Test whether \a x is solution @@ -2429,9 +2429,8 @@ namespace Test { namespace Int { /// Create and register test AbsXY(const std::string& s, const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test("Arithmetic::Abs::XY::"+str(ipl)+"::"+s,2,d,false,ipl) { - add_tags(TestTag::check); - } + : Test(TestTags(TestTag::normal,TestTag::check), + "Arithmetic::Abs::XY::"+str(ipl)+"::"+s,2,d,false,ipl) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { double d0 = static_cast(x[0]); @@ -2450,9 +2449,8 @@ namespace Test { namespace Int { /// Create and register test AbsXX(const std::string& s, const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test("Arithmetic::Abs::XX::"+str(ipl)+"::"+s,1,d,false,ipl) { - add_tags(TestTag::check); - } + : Test(TestTags(TestTag::normal,TestTag::check), + "Arithmetic::Abs::XX::"+str(ipl)+"::"+s,1,d,false,ipl) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { double d0 = static_cast(x[0]); @@ -2678,9 +2676,8 @@ namespace Test { namespace Int { public: /// Create and register test MaxNary(Gecode::IntPropLevel ipl) - : Test("Arithmetic::Max::Nary::"+str(ipl),4,-4,4,false,ipl) { - add_tags(TestTag::check); - } + : Test(TestTags(TestTag::normal,TestTag::check), + "Arithmetic::Max::Nary::"+str(ipl),4,-4,4,false,ipl) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { return std::max(std::max(x[0],x[1]), x[2]) == x[3]; @@ -2698,9 +2695,9 @@ namespace Test { namespace Int { public: /// Create and register test MaxNaryShared(Gecode::IntPropLevel ipl) - : Test("Arithmetic::Max::Nary::Shared::"+str(ipl),3,-4,4,false,ipl) { - add_tags(TestTag::check); - } + : Test(TestTags(TestTag::normal,TestTag::check), + "Arithmetic::Max::Nary::Shared::"+str(ipl), + 3,-4,4,false,ipl) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { return std::max(std::max(x[0],x[1]), x[2]) == x[1]; @@ -2723,12 +2720,11 @@ namespace Test { namespace Int { public: /// Create and register test ArgMax(int n, int o, bool tb) - : Test("Arithmetic::ArgMax::"+str(o)+"::"+str(tb)+"::"+str(n), + : Test(TestTags(TestTag::normal,TestTag::check), + "Arithmetic::ArgMax::"+str(o)+"::"+str(tb)+"::"+str(n), n+1,0,n+1, false,tb ? Gecode::IPL_DEF : Gecode::IPL_DOM), - offset(o), tiebreak(tb) { - add_tags(TestTag::check); - } + offset(o), tiebreak(tb) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { int n=x.size()-1; @@ -2759,10 +2755,10 @@ namespace Test { namespace Int { public: /// Create and register test ArgMaxShared(int n, bool tb) - : Test("Arithmetic::ArgMax::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1, + : Test(TestTags(TestTag::normal,TestTag::check), + "Arithmetic::ArgMax::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1, false), tiebreak(tb) { - add_tags(TestTag::check); testfix=false; } /// %Test whether \a x is solution @@ -2874,12 +2870,11 @@ namespace Test { namespace Int { public: /// Create and register test ArgMaxBool(int n, int o, bool tb) - : Test("Arithmetic::ArgMaxBool::"+str(o)+"::"+str(tb)+"::"+str(n), + : Test(TestTags(TestTag::normal,TestTag::check), + "Arithmetic::ArgMaxBool::"+str(o)+"::"+str(tb)+"::"+str(n), n+1,0,n+1, false,tb ? Gecode::IPL_DEF : Gecode::IPL_DOM), - offset(o), tiebreak(tb) { - add_tags(TestTag::check); - } + offset(o), tiebreak(tb) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { int n=x.size()-1; @@ -2915,10 +2910,10 @@ namespace Test { namespace Int { public: /// Create and register test ArgMaxBoolShared(int n, bool tb) - : Test("Arithmetic::ArgMaxBool::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1, + : Test(TestTags(TestTag::normal,TestTag::check), + "Arithmetic::ArgMaxBool::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1, false), tiebreak(tb) { - add_tags(TestTag::check); testfix=false; } /// %Test whether \a x is solution @@ -3171,10 +3166,12 @@ namespace Test { namespace Int { (void) new PowXY("C",n,c,ipls.ipl()); (void) new PowXY("D",n,d,ipls.ipl()); - (void) new PowXX("A",n,a,ipls.ipl()); - (void) new PowXX("B",n,b,ipls.ipl()); - (void) new PowXX("C",n,c,ipls.ipl()); - (void) new PowXX("D",n,d,ipls.ipl()); + TestTags tags = (n == 0) && (ipls.ipl() == Gecode::IPL_BND) + ? TestTag::normal : TestTag::sweep; + (void) new PowXX(tags,"A",n,a,ipls.ipl()); + (void) new PowXX(TestTag::sweep,"B",n,b,ipls.ipl()); + (void) new PowXX(TestTag::sweep,"C",n,c,ipls.ipl()); + (void) new PowXX(TestTag::sweep,"D",n,d,ipls.ipl()); } for (int n=1; n<=6; n++) { @@ -3183,17 +3180,19 @@ namespace Test { namespace Int { (void) new NrootXY("C",n,c,ipls.ipl()); (void) new NrootXY("D",n,d,ipls.ipl()); - (void) new NrootXX("A",n,a,ipls.ipl()); - (void) new NrootXX("B",n,b,ipls.ipl()); - (void) new NrootXX("C",n,c,ipls.ipl()); - (void) new NrootXX("D",n,d,ipls.ipl()); + TestTags tags = (n == 1) && (ipls.ipl() == Gecode::IPL_BND) + ? TestTag::normal : TestTag::sweep; + (void) new NrootXX(tags,"A",n,a,ipls.ipl()); + (void) new NrootXX(TestTag::sweep,"B",n,b,ipls.ipl()); + (void) new NrootXX(TestTag::sweep,"C",n,c,ipls.ipl()); + (void) new NrootXX(TestTag::sweep,"D",n,d,ipls.ipl()); } for (int n=30; n<=34; n++) { (void) new PowXY("C",n,c,ipls.ipl()); - (void) new PowXX("C",n,c,ipls.ipl()); + (void) new PowXX(TestTag::sweep,"C",n,c,ipls.ipl()); (void) new NrootXY("C",n,c,ipls.ipl()); - (void) new NrootXX("C",n,c,ipls.ipl()); + (void) new NrootXX(TestTag::sweep,"C",n,c,ipls.ipl()); } (void) new SqrtXY("A",a,ipls.ipl()); diff --git a/test/int/channel.cpp b/test/int/channel.cpp index e1f4e12b3e..abb7b9e6c2 100644 --- a/test/int/channel.cpp +++ b/test/int/channel.cpp @@ -168,9 +168,9 @@ namespace Test { namespace Int { int o; public: /// Construct and register test - ChannelLinkMulti(const std::string& s, int min, int max, int o0) - : Test(s == "A" ? TestTag::normal : TestTag::sweep, - "Channel::Bool::Multi::"+s,7,min,max), o(o0) { + ChannelLinkMulti(TestTags tags, const std::string& s, + int min, int max, int o0) + : Test(tags,"Channel::Bool::Multi::"+s,7,min,max), o(o0) { } /// Check whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -219,9 +219,9 @@ namespace Test { namespace Int { ChannelLinkSingle cls; - ChannelLinkMulti clma("A", 0, 5, 0); - ChannelLinkMulti clmb("B", 1, 6, 1); - ChannelLinkMulti clmc("C",-1, 4,-1); + ChannelLinkMulti clma(TestTag::normal,"A", 0, 5, 0); + ChannelLinkMulti clmb(TestTag::sweep,"B", 1, 6, 1); + ChannelLinkMulti clmc(TestTag::sweep,"C",-1, 4,-1); //@} } diff --git a/test/int/cumulative.cpp b/test/int/cumulative.cpp index 8643c45221..e83cfdecab 100755 --- a/test/int/cumulative.cpp +++ b/test/int/cumulative.cpp @@ -76,14 +76,13 @@ namespace Test { namespace Int { const Gecode::IntArgs& u0, int o0, Gecode::IntPropLevel ipl0) - : Test(TestTag::sweep,"Cumulative::Man::Fix::"+str(o0)+"::"+ + : Test((o0 == 0) && (c0 == 4) + ? TestTags(TestTag::normal,TestTag::check) + : TestTags(TestTag::sweep), + "Cumulative::Man::Fix::"+str(o0)+"::"+ str(c0)+"::"+str(p0)+"::"+str(u0)+"::"+str(ipl0), (c0 >= 0) ? p0.size():p0.size()+1,0,st(c0,p0,u0),false,ipl0), c(c0), p(p0), u(u0), o(o0) { - if ((o0 == 0) && (c0 == 4)) { - tags(TestTag::normal); - add_tags(TestTag::check); - } testsearch = false; testfix = false; contest = CTL_NONE; @@ -183,13 +182,13 @@ namespace Test { namespace Int { const Gecode::IntArgs& u0, int o0, Gecode::IntPropLevel ipl0) - : Test(TestTag::sweep,"Cumulative::Opt::Fix::"+str(o0)+"::"+ + : Test((o0 == Gecode::Int::Limits::min) && (c0 == -1) + ? TestTags(TestTag::normal) : TestTags(TestTag::sweep), + "Cumulative::Opt::Fix::"+str(o0)+"::"+ str(c0)+"::"+str(p0)+"::"+str(u0)+"::"+str(ipl0), (c0 >= 0) ? 2*p0.size() : 2*p0.size()+1,0,st(c0,p0,u0), false,ipl0), c(c0), p(p0), u(u0), l(st(c,p,u)/2), o(o0) { - if ((o0 == Gecode::Int::Limits::min) && (c0 == -1)) - tags(TestTag::normal); testsearch = false; testfix = false; contest = CTL_NONE; @@ -404,16 +403,16 @@ namespace Test { namespace Int { const Gecode::IntArgs& u0, int o0, Gecode::IntPropLevel ipl0) - : Test(TestTag::sweep,"Cumulative::Opt::Flex::"+str(o0)+"::"+ + : Test((o0 == Gecode::Int::Limits::min) && (c0 == 4) && + (minP == 0) && (maxP == 2) + ? TestTags(TestTag::normal) : TestTags(TestTag::sweep), + "Cumulative::Opt::Flex::"+str(o0)+"::"+ str(c0)+"::"+str(minP)+"::"+str(maxP)+"::"+str(u0)+ "::"+str(ipl0), (c0 >= 0) ? 3*u0.size() : 3*u0.size()+1, 0,std::max(maxP,st(c0,maxP,u0)), false,ipl0), c(c0), _minP(minP), _maxP(maxP), u(u0), l(std::max(maxP,st(c0,maxP,u0))/2), o(o0) { - if ((o0 == Gecode::Int::Limits::min) && (c0 == 4) && - (minP == 0) && (maxP == 2)) - tags(TestTag::normal); testsearch = false; testfix = false; contest = CTL_NONE; diff --git a/test/int/distinct.cpp b/test/int/distinct.cpp index f4f8582104..182e7076fc 100755 --- a/test/int/distinct.cpp +++ b/test/int/distinct.cpp @@ -174,8 +174,8 @@ namespace Test { namespace Int { public: /// Create and register test Random(int n, int min, int max, Gecode::IntPropLevel ipl) - : Test("Distinct::Random::"+str(ipl),n,min,max,false,ipl) { - add_tags(TestTag::check); + : Test(TestTags(TestTag::normal,TestTag::check), + "Distinct::Random::"+str(ipl),n,min,max,false,ipl) { testsearch = false; } /// Create and register initial assignment diff --git a/test/int/extensional.cpp b/test/int/extensional.cpp index 48ea02f718..7099020260 100755 --- a/test/int/extensional.cpp +++ b/test/int/extensional.cpp @@ -945,7 +945,7 @@ namespace Test { namespace Int { class SparseTupleSetUnary : public ::Test::Base { public: SparseTupleSetUnary(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::Unary", TestTag::sweep) {} + : ::Test::Base("Int::Extensional::TupleSet::Sparse::Unary") {} virtual bool run(void) { using namespace Gecode; @@ -997,7 +997,7 @@ namespace Test { namespace Int { class SparseTupleSetTernary : public ::Test::Base { public: SparseTupleSetTernary(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::Ternary", TestTag::sweep) {} + : ::Test::Base("Int::Extensional::TupleSet::Sparse::Ternary") {} virtual bool run(void) { using namespace Gecode; @@ -1051,7 +1051,7 @@ namespace Test { namespace Int { class SparseTupleSetHighArity : public ::Test::Base { public: SparseTupleSetHighArity(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::HighArity", TestTag::sweep) {} + : ::Test::Base("Int::Extensional::TupleSet::Sparse::HighArity") {} virtual bool run(void) { using namespace Gecode; @@ -1113,7 +1113,7 @@ namespace Test { namespace Int { class SparseTupleSetNullary : public ::Test::Base { public: SparseTupleSetNullary(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::Nullary", TestTag::sweep) {} + : ::Test::Base("Int::Extensional::TupleSet::Sparse::Nullary") {} virtual bool run(void) { using namespace Gecode; @@ -1172,9 +1172,9 @@ namespace Test { namespace Int { class SparseTupleSetIncrementalDelta : public ::Test::Base { public: SparseTupleSetIncrementalDelta(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::IncrementalDelta") { - add_tags(TestTag::check); - } + : ::Test::Base( + "Int::Extensional::TupleSet::Sparse::IncrementalDelta", + TestTags(TestTag::normal,TestTag::check)) {} virtual bool run(void) { using namespace Gecode; @@ -1228,7 +1228,7 @@ namespace Test { namespace Int { class SparseTupleSetIncrementalAssign : public ::Test::Base { public: SparseTupleSetIncrementalAssign(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::IncrementalAssign", TestTag::sweep) {} + : ::Test::Base("Int::Extensional::TupleSet::Sparse::IncrementalAssign") {} virtual bool run(void) { using namespace Gecode; @@ -1274,7 +1274,7 @@ namespace Test { namespace Int { class SparseTupleSetIncrementalBool : public ::Test::Base { public: SparseTupleSetIncrementalBool(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::IncrementalBool", TestTag::sweep) {} + : ::Test::Base("Int::Extensional::TupleSet::Sparse::IncrementalBool") {} virtual bool run(void) { using namespace Gecode; @@ -1325,7 +1325,7 @@ namespace Test { namespace Int { class SparseTupleSetDisabledFailure : public ::Test::Base { public: SparseTupleSetDisabledFailure(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::DisabledFailure", TestTag::sweep) {} + : ::Test::Base("Int::Extensional::TupleSet::Sparse::DisabledFailure") {} virtual bool run(void) { using namespace Gecode; @@ -1374,7 +1374,7 @@ namespace Test { namespace Int { class SparseTupleSetWideDelta : public ::Test::Base { public: SparseTupleSetWideDelta(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::WideDelta", TestTag::sweep) {} + : ::Test::Base("Int::Extensional::TupleSet::Sparse::WideDelta") {} virtual bool run(void) { using namespace Gecode; @@ -1443,7 +1443,7 @@ namespace Test { namespace Int { class SparseTupleSetNegative : public ::Test::Base { public: SparseTupleSetNegative(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::Negative", TestTag::sweep) {} + : ::Test::Base("Int::Extensional::TupleSet::Sparse::Negative") {} virtual bool run(void) { using namespace Gecode; @@ -1491,7 +1491,7 @@ namespace Test { namespace Int { class SparseTupleSetReified : public ::Test::Base { public: SparseTupleSetReified(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::Reified", TestTag::sweep) {} + : ::Test::Base("Int::Extensional::TupleSet::Sparse::Reified") {} virtual bool run(void) { using namespace Gecode; @@ -1542,7 +1542,8 @@ namespace Test { namespace Int { class TupleSetSingleRepresentation : public ::Test::Base { public: TupleSetSingleRepresentation(void) - : ::Test::Base("Int::Extensional::TupleSet::Support::SingleRepresentation", TestTag::sweep) {} + : ::Test::Base( + "Int::Extensional::TupleSet::Support::SingleRepresentation") {} virtual bool run(void) { using namespace Gecode; @@ -1611,8 +1612,7 @@ namespace Test { namespace Int { public: TupleSetSupportOffsetBoundary(void) : ::Test::Base( - "Int::Extensional::TupleSet::Support::OffsetBoundary", - TestTag::sweep) {} + "Int::Extensional::TupleSet::Support::OffsetBoundary") {} virtual bool run(void) { using Gecode::Int::Extensional::support_offsets_size; @@ -1634,8 +1634,7 @@ namespace Test { namespace Int { public: TupleSetTerminalFinalizationFailure(void) : ::Test::Base( - "Int::Extensional::TupleSet::Support::TerminalFailure", - TestTag::sweep) {} + "Int::Extensional::TupleSet::Support::TerminalFailure") {} virtual bool run(void) { using namespace Gecode; @@ -1703,8 +1702,7 @@ namespace Test { namespace Int { public: TupleSetDFARepresentation(void) : ::Test::Base( - "Int::Extensional::TupleSet::Support::DFARepresentation", - TestTag::sweep) {} + "Int::Extensional::TupleSet::Support::DFARepresentation") {} virtual bool run(void) { using namespace Gecode; @@ -1735,8 +1733,7 @@ namespace Test { namespace Int { public: TupleSetDisabledClone(void) : ::Test::Base( - "Int::Extensional::TupleSet::Support::DisabledClone", - TestTag::sweep) {} + "Int::Extensional::TupleSet::Support::DisabledClone") {} virtual bool run(void) { using namespace Gecode; @@ -1860,9 +1857,9 @@ namespace Test { namespace Int { class TupleSetAutoDefaultDispatch : public ::Test::Base { public: TupleSetAutoDefaultDispatch(void) - : ::Test::Base("Int::Extensional::TupleSet::Auto::DefaultDispatch") { - add_tags(TestTag::check); - } + : ::Test::Base( + "Int::Extensional::TupleSet::Auto::DefaultDispatch", + TestTags(TestTag::normal,TestTag::check)) {} virtual bool run(void) { using namespace Gecode; @@ -1958,7 +1955,8 @@ namespace Test { namespace Int { class DenseCompressedTupleSetWideGap : public ::Test::Base { public: DenseCompressedTupleSetWideGap(void) - : ::Test::Base("Int::Extensional::TupleSet::DenseCompressed::WideGap", TestTag::sweep) {} + : ::Test::Base( + "Int::Extensional::TupleSet::DenseCompressed::WideGap") {} virtual bool run(void) { using namespace Gecode; @@ -2070,7 +2068,8 @@ namespace Test { namespace Int { class SparseTupleSetNegativeFail : public ::Test::Base { public: SparseTupleSetNegativeFail(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::NegativeFail", TestTag::sweep) {} + : ::Test::Base( + "Int::Extensional::TupleSet::Sparse::NegativeFail") {} virtual bool run(void) { using namespace Gecode; @@ -2110,7 +2109,8 @@ namespace Test { namespace Int { class SparseTupleSetNegativePrune : public ::Test::Base { public: SparseTupleSetNegativePrune(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::NegativePrune", TestTag::sweep) {} + : ::Test::Base( + "Int::Extensional::TupleSet::Sparse::NegativePrune") {} virtual bool run(void) { using namespace Gecode; @@ -2156,7 +2156,8 @@ namespace Test { namespace Int { class SparseTupleSetReifiedModes : public ::Test::Base { public: SparseTupleSetReifiedModes(void) - : ::Test::Base("Int::Extensional::TupleSet::Sparse::ReifiedModes", TestTag::sweep) {} + : ::Test::Base( + "Int::Extensional::TupleSet::Sparse::ReifiedModes") {} virtual bool run(void) { using namespace Gecode; diff --git a/test/int/linear.cpp b/test/int/linear.cpp index 7e029a495f..6b8706b796 100755 --- a/test/int/linear.cpp +++ b/test/int/linear.cpp @@ -64,13 +64,10 @@ namespace Test { namespace Int { int c; public: /// Create and register test - IntInt(const std::string& s, const Gecode::IntSet& d, + IntInt(TestTags tags, const std::string& s, const Gecode::IntSet& d, const Gecode::IntArgs& a0, Gecode::IntRelType irt0, int c0, Gecode::IntPropLevel ipl=Gecode::IPL_BND) - : Test((s == "11") && (irt0 == Gecode::IRT_EQ) && - (ipl == Gecode::IPL_BND) && (c0 == 0) && - (a0.size() == 1) ? TestTag::normal : TestTag::sweep, - "Linear::Int::Int::"+ + : Test(tags,"Linear::Int::Int::"+ str(irt0)+"::"+str(ipl)+"::"+s+"::"+str(c0)+"::" +str(a0.size()), a0.size(),d,ipl != Gecode::IPL_DOM,ipl), @@ -164,14 +161,12 @@ namespace Test { namespace Int { /// Create and register test BoolInt(const std::string& s, const Gecode::IntArgs& a0, Gecode::IntRelType irt0, int c0) - : Test(TestTag::sweep,"Linear::Bool::Int::"+ + : Test(irt0 == Gecode::IRT_LQ + ? TestTags(TestTag::normal,TestTag::check) + : TestTags(TestTag::sweep),"Linear::Bool::Int::"+ str(irt0)+"::"+s+"::"+str(a0.size())+"::"+str(c0), a0.size(),0,1,true,Gecode::IPL_DEF), a(a0), irt(irt0), c(c0) { - if (irt0 == Gecode::IRT_LQ) { - tags(TestTag::normal); - add_tags(TestTag::check); - } testfix=false; } /// %Test whether \a x is solution @@ -281,15 +276,17 @@ namespace Test { namespace Int { IntArgs a1({0}); for (IntRelTypes irts; irts(); ++irts) { - (void) new IntInt("11",d1,a1,irts.irt(),0); + TestTags tags = irts.irt() == Gecode::IRT_EQ + ? TestTag::normal : TestTag::sweep; + (void) new IntInt(tags,"11",d1,a1,irts.irt(),0); (void) new IntVar("11",d1,a1,irts.irt()); - (void) new IntInt("21",d2,a1,irts.irt(),0); + (void) new IntInt(TestTag::sweep,"21",d2,a1,irts.irt(),0); (void) new IntVar("21",d2,a1,irts.irt()); - (void) new IntInt("31",d3,a1,irts.irt(),150000000); + (void) new IntInt(TestTag::sweep,"31",d3,a1,irts.irt(),150000000); } - (void) new IntInt("11",d1,a1,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTag::sweep,"11",d1,a1,IRT_EQ,0,IPL_DOM); (void) new IntVar("11",d1,a1,IRT_EQ,IPL_DOM); - (void) new IntInt("21",d2,a1,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTag::sweep,"21",d2,a1,IRT_EQ,0,IPL_DOM); (void) new IntVar("21",d2,a1,IRT_EQ,IPL_DOM); const int av2[5] = {1,1,1,1,1}; @@ -304,15 +301,15 @@ namespace Test { namespace Int { IntArgs a4(i, av4); IntArgs a5(i, av5); for (IntRelTypes irts; irts(); ++irts) { - (void) new IntInt("12",d1,a2,irts.irt(),0); - (void) new IntInt("13",d1,a3,irts.irt(),0); - (void) new IntInt("14",d1,a4,irts.irt(),0); - (void) new IntInt("15",d1,a5,irts.irt(),0); - (void) new IntInt("22",d2,a2,irts.irt(),0); - (void) new IntInt("23",d2,a3,irts.irt(),0); - (void) new IntInt("24",d2,a4,irts.irt(),0); - (void) new IntInt("25",d2,a5,irts.irt(),0); - (void) new IntInt("32",d3,a2,irts.irt(),1500000000); + (void) new IntInt(TestTag::sweep,"12",d1,a2,irts.irt(),0); + (void) new IntInt(TestTag::sweep,"13",d1,a3,irts.irt(),0); + (void) new IntInt(TestTag::sweep,"14",d1,a4,irts.irt(),0); + (void) new IntInt(TestTag::sweep,"15",d1,a5,irts.irt(),0); + (void) new IntInt(TestTag::sweep,"22",d2,a2,irts.irt(),0); + (void) new IntInt(TestTag::sweep,"23",d2,a3,irts.irt(),0); + (void) new IntInt(TestTag::sweep,"24",d2,a4,irts.irt(),0); + (void) new IntInt(TestTag::sweep,"25",d2,a5,irts.irt(),0); + (void) new IntInt(TestTag::sweep,"32",d3,a2,irts.irt(),1500000000); if (i < 5) { (void) new IntVar("12",d1,a2,irts.irt()); (void) new IntVar("13",d1,a3,irts.irt()); @@ -324,14 +321,14 @@ namespace Test { namespace Int { (void) new IntVar("25",d2,a5,irts.irt()); } } - (void) new IntInt("12",d1,a2,IRT_EQ,0,IPL_DOM); - (void) new IntInt("13",d1,a3,IRT_EQ,0,IPL_DOM); - (void) new IntInt("14",d1,a4,IRT_EQ,0,IPL_DOM); - (void) new IntInt("15",d1,a5,IRT_EQ,0,IPL_DOM); - (void) new IntInt("22",d2,a2,IRT_EQ,0,IPL_DOM); - (void) new IntInt("23",d2,a3,IRT_EQ,0,IPL_DOM); - (void) new IntInt("24",d2,a4,IRT_EQ,0,IPL_DOM); - (void) new IntInt("25",d2,a5,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTag::sweep,"12",d1,a2,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTag::sweep,"13",d1,a3,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTag::sweep,"14",d1,a4,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTag::sweep,"15",d1,a5,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTag::sweep,"22",d2,a2,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTag::sweep,"23",d2,a3,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTag::sweep,"24",d2,a4,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTag::sweep,"25",d2,a5,IRT_EQ,0,IPL_DOM); if (i < 4) { (void) new IntVar("12",d1,a2,IRT_EQ,IPL_DOM); (void) new IntVar("13",d1,a3,IRT_EQ,IPL_DOM); diff --git a/test/int/mm-lin.cpp b/test/int/mm-lin.cpp index 6b0a267187..4cbd1db91c 100755 --- a/test/int/mm-lin.cpp +++ b/test/int/mm-lin.cpp @@ -164,11 +164,9 @@ namespace Test { namespace Int { const LinInstr* lis; public: /// Create and register test - LinExprBool(const LinInstr* lis0, const std::string& s) - : Test(s == "352" ? TestTag::normal : TestTag::sweep, - "MiniModel::LinExpr::Bool::"+s,4,-3,3), lis(lis0) { - if (s == "352") - add_tags(TestTag::check); + LinExprBool(TestTags tags, const LinInstr* lis0, + const std::string& s) + : Test(tags,"MiniModel::LinExpr::Bool::"+s,4,-3,3), lis(lis0) { testfix = false; } /// %Test whether \a x is solution @@ -2198,7 +2196,10 @@ namespace Test { namespace Int { s = "0" + s; } (void) new LinExprInt(li[i],s); - (void) new LinExprBool(li[i],s); + TestTags bool_tags = (i == 352) + ? TestTags(TestTag::normal,TestTag::check) + : TestTags(TestTag::sweep); + (void) new LinExprBool(bool_tags,li[i],s); (void) new LinExprMixed(li[i],s); } IntRelTypes irts; diff --git a/test/int/no-overlap.cpp b/test/int/no-overlap.cpp index c7283c18c5..069a143ae2 100755 --- a/test/int/no-overlap.cpp +++ b/test/int/no-overlap.cpp @@ -55,10 +55,9 @@ namespace Test { namespace Int { Gecode::IntArgs h; public: /// Create and register test with maximal coordinate value \a m - Int2(int m, const Gecode::IntArgs& w0, const Gecode::IntArgs& h0) - : Test((m == 2) && (str(w0) == "[1,1,1,1]") && - (str(h0) == "[1,1,1,1]") - ? TestTag::normal : TestTag::sweep, + Int2(TestTags tags, int m, + const Gecode::IntArgs& w0, const Gecode::IntArgs& h0) + : Test(tags, "NoOverlap::Int::2::"+str(m)+"::"+str(w0)+"::"+str(h0), 2*w0.size(), 0, m-1), w(w0), h(h0) { @@ -271,12 +270,12 @@ namespace Test { namespace Int { IntArgs s4({1,1,1,1}); for (int m=2; m<3; m++) { - (void) new Int2(m, s1, s1); - (void) new Int2(m, s2, s2); - (void) new Int2(m, s3, s3); - (void) new Int2(m, s2, s3); - (void) new Int2(m, s4, s4); - (void) new Int2(m, s4, s2); + (void) new Int2(TestTag::sweep,m,s1,s1); + (void) new Int2(TestTag::sweep,m,s2,s2); + (void) new Int2(TestTag::sweep,m,s3,s3); + (void) new Int2(TestTag::sweep,m,s2,s3); + (void) new Int2(TestTag::normal,m,s4,s4); + (void) new Int2(TestTag::sweep,m,s4,s2); (void) new IntOpt2(m, s2, s3); (void) new IntOpt2(m, s4, s3); } diff --git a/test/int/nvalues.cpp b/test/int/nvalues.cpp index 76d3d54cf3..4b81a4c2b5 100644 --- a/test/int/nvalues.cpp +++ b/test/int/nvalues.cpp @@ -53,9 +53,8 @@ namespace Test { namespace Int { int m; public: /// Create and register test - IntInt(int n, int m0, Gecode::IntRelType irt0) - : Test((n == 1) && (m0 == 0) && (irt0 == Gecode::IRT_EQ) - ? TestTag::normal : TestTag::sweep, + IntInt(TestTags tags, int n, int m0, Gecode::IntRelType irt0) + : Test(tags, "NValues::Int::Int::"+str(irt0)+"::"+str(n)+"::"+str(m0), n,0,n), irt(irt0), m(m0) { @@ -98,8 +97,8 @@ namespace Test { namespace Int { Gecode::IntRelType irt; public: /// Create and register test - IntVar(int n, Gecode::IntRelType irt0) - : Test(TestTag::sweep, + IntVar(TestTags tags, int n, Gecode::IntRelType irt0) + : Test(tags, "NValues::Int::Var::"+str(irt0)+"::"+str(n),n+1,0,n), irt(irt0) { testfix = false; @@ -221,10 +220,18 @@ namespace Test { namespace Int { (void) new BoolVar(i, irts.irt()); } for (int i=1; i<=7; i += 2) { - for (int m=0; m<=i+1; m++) - (void) new IntInt(i, m, irts.irt()); - if (i <= 5) - (void) new IntVar(i, irts.irt()); + for (int m=0; m<=i+1; m++) { + TestTags tags = ((i == 3) && (m == 2) && + (irts.irt() == Gecode::IRT_EQ)) + ? TestTag::normal : TestTag::sweep; + (void) new IntInt(tags,i,m,irts.irt()); + } + if (i <= 5) { + TestTags tags = ((i == 3) && + (irts.irt() == Gecode::IRT_EQ)) + ? TestTag::normal : TestTag::sweep; + (void) new IntVar(tags,i,irts.irt()); + } } } } diff --git a/test/int/unary.cpp b/test/int/unary.cpp index 944dd9d105..2cbc925815 100755 --- a/test/int/unary.cpp +++ b/test/int/unary.cpp @@ -61,14 +61,11 @@ namespace Test { namespace Int { namespace Unary { } public: /// Create and register test - ManFixPUnary(const Gecode::IntArgs& p0, int o, Gecode::IntPropLevel ipl0) - : Test(TestTag::sweep,"Unary::Man::Fix::"+str(o)+"::"+str(p0)+"::"+str(ipl0), + ManFixPUnary(TestTags tags, const Gecode::IntArgs& p0, + int o, Gecode::IntPropLevel ipl0) + : Test(tags,"Unary::Man::Fix::"+str(o)+"::"+str(p0)+"::"+str(ipl0), p0.size(),o,o+st(p0),false,ipl0), p(p0) { - if ((o == Gecode::Int::Limits::min) && - (str(p0) == "[2,2,0,2,2]") && - (ipl0 == Gecode::IPL_ADVANCED)) - tags(TestTag::normal); testsearch = false; contest = CTL_NONE; } @@ -106,13 +103,10 @@ namespace Test { namespace Int { namespace Unary { } public: /// Create and register test - OptFixPUnary(const Gecode::IntArgs& p0, int o, Gecode::IntPropLevel ipl0) - : Test(TestTag::sweep,"Unary::Opt::Fix::"+str(o)+"::"+str(p0)+"::"+str(ipl0), + OptFixPUnary(TestTags tags, const Gecode::IntArgs& p0, + int o, Gecode::IntPropLevel ipl0) + : Test(tags,"Unary::Opt::Fix::"+str(o)+"::"+str(p0)+"::"+str(ipl0), 2*p0.size(),o,o+st(p0),false,ipl0), p(p0), l(o+st(p)/2) { - if ((o == Gecode::Int::Limits::min) && - (str(p0) == "[2,2,0,2,2]") && - (ipl0 == Gecode::IPL_ADVANCED)) - tags(TestTag::normal); testsearch = false; contest = CTL_NONE; } @@ -155,13 +149,11 @@ namespace Test { namespace Int { namespace Unary { int off; public: /// Create and register test - ManFlexUnary(int n, int minP, int maxP, int o, Gecode::IntPropLevel ipl0) - : Test(TestTag::sweep,"Unary::Man::Flex::"+str(o)+"::"+str(n)+"::" + ManFlexUnary(TestTags tags, int n, int minP, int maxP, + int o, Gecode::IntPropLevel ipl0) + : Test(tags,"Unary::Man::Flex::"+str(o)+"::"+str(n)+"::" +str(minP)+"::"+str(maxP)+"::"+str(ipl0), 2*n,0,n*maxP,false,ipl0), _minP(minP), _maxP(maxP), off(o) { - if ((o == Gecode::Int::Limits::min) && (n == 4) && - (minP == 0) && (maxP == 2) && (ipl0 == Gecode::IPL_ADVANCED)) - tags(TestTag::normal); testsearch = false; testfix = false; contest = CTL_NONE; @@ -217,14 +209,12 @@ namespace Test { namespace Int { namespace Unary { } public: /// Create and register test - OptFlexUnary(int n, int minP, int maxP, int o, Gecode::IntPropLevel ipl0) - : Test(TestTag::sweep,"Unary::Opt::Flex::"+str(o)+"::"+str(n)+"::" + OptFlexUnary(TestTags tags, int n, int minP, int maxP, + int o, Gecode::IntPropLevel ipl0) + : Test(tags,"Unary::Opt::Flex::"+str(o)+"::"+str(n)+"::" +str(minP)+"::"+str(maxP)+"::"+str(ipl0), 3*n,0,n*maxP,false,ipl0), _minP(minP), _maxP(maxP), off(o), l(n*maxP/2) { - if ((o == Gecode::Int::Limits::min) && (n == 4) && - (minP == 0) && (maxP == 2) && (ipl0 == Gecode::IPL_ADVANCED)) - tags(TestTag::normal); testsearch = false; testfix = false; contest = CTL_NONE; @@ -282,61 +272,63 @@ namespace Test { namespace Int { namespace Unary { IntArgs p30({4,0,2,9,3,7,5,0}); for (IntPropBasicAdvanced ipba; ipba(); ++ipba) { - (void) new ManFixPUnary(p1,0,ipba.ipl()); - (void) new ManFixPUnary(p1,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFixPUnary(p1,0,ipba.ipl()); - (void) new OptFixPUnary(p1,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(4,0,2,0,ipba.ipl()); - (void) new ManFlexUnary(4,0,2,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(4,1,3,0,ipba.ipl()); - (void) new ManFlexUnary(4,1,3,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFlexUnary(4,0,2,0,ipba.ipl()); - (void) new OptFlexUnary(4,0,2,Gecode::Int::Limits::min,ipba.ipl()); + TestTags representative = ipba.ipl() == Gecode::IPL_ADVANCED + ? TestTag::normal : TestTag::sweep; + (void) new ManFixPUnary(TestTag::sweep,p1,0,ipba.ipl()); + (void) new ManFixPUnary(TestTag::sweep,p1,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFixPUnary(TestTag::sweep,p1,0,ipba.ipl()); + (void) new OptFixPUnary(TestTag::sweep,p1,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,4,0,2,0,ipba.ipl()); + (void) new ManFlexUnary(representative,4,0,2,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,4,1,3,0,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,4,1,3,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFlexUnary(TestTag::sweep,4,0,2,0,ipba.ipl()); + (void) new OptFlexUnary(representative,4,0,2,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFixPUnary(p10,0,ipba.ipl()); - (void) new ManFixPUnary(p10,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFixPUnary(p10,0,ipba.ipl()); - (void) new OptFixPUnary(p10,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(5,0,2,0,ipba.ipl()); - (void) new ManFlexUnary(5,0,2,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFlexUnary(5,0,2,0,ipba.ipl()); - (void) new OptFlexUnary(5,0,2,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFixPUnary(TestTag::sweep,p10,0,ipba.ipl()); + (void) new ManFixPUnary(representative,p10,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFixPUnary(TestTag::sweep,p10,0,ipba.ipl()); + (void) new OptFixPUnary(representative,p10,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,5,0,2,0,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,5,0,2,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFlexUnary(TestTag::sweep,5,0,2,0,ipba.ipl()); + (void) new OptFlexUnary(TestTag::sweep,5,0,2,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFixPUnary(p2,0,ipba.ipl()); - (void) new ManFixPUnary(p2,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFixPUnary(p2,0,ipba.ipl()); - (void) new OptFixPUnary(p2,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(4,3,5,0,ipba.ipl()); - (void) new ManFlexUnary(4,3,5,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFlexUnary(4,3,5,0,ipba.ipl()); - (void) new OptFlexUnary(4,3,5,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFixPUnary(TestTag::sweep,p2,0,ipba.ipl()); + (void) new ManFixPUnary(TestTag::sweep,p2,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFixPUnary(TestTag::sweep,p2,0,ipba.ipl()); + (void) new OptFixPUnary(TestTag::sweep,p2,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,4,3,5,0,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,4,3,5,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFlexUnary(TestTag::sweep,4,3,5,0,ipba.ipl()); + (void) new OptFlexUnary(TestTag::sweep,4,3,5,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFixPUnary(p20,0,ipba.ipl()); - (void) new ManFixPUnary(p20,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFixPUnary(p20,0,ipba.ipl()); - (void) new OptFixPUnary(p20,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(6,0,5,0,ipba.ipl()); - (void) new ManFlexUnary(6,0,5,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFlexUnary(6,0,5,0,ipba.ipl()); - (void) new OptFlexUnary(6,0,5,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFixPUnary(TestTag::sweep,p20,0,ipba.ipl()); + (void) new ManFixPUnary(TestTag::sweep,p20,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFixPUnary(TestTag::sweep,p20,0,ipba.ipl()); + (void) new OptFixPUnary(TestTag::sweep,p20,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,6,0,5,0,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,6,0,5,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFlexUnary(TestTag::sweep,6,0,5,0,ipba.ipl()); + (void) new OptFlexUnary(TestTag::sweep,6,0,5,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFixPUnary(p3,0,ipba.ipl()); - (void) new ManFixPUnary(p3,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFixPUnary(p3,0,ipba.ipl()); - (void) new OptFixPUnary(p3,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(6,2,7,0,ipba.ipl()); - (void) new ManFlexUnary(6,2,7,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFlexUnary(6,2,7,0,ipba.ipl()); - (void) new OptFlexUnary(6,2,7,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFixPUnary(TestTag::sweep,p3,0,ipba.ipl()); + (void) new ManFixPUnary(TestTag::sweep,p3,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFixPUnary(TestTag::sweep,p3,0,ipba.ipl()); + (void) new OptFixPUnary(TestTag::sweep,p3,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,6,2,7,0,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,6,2,7,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFlexUnary(TestTag::sweep,6,2,7,0,ipba.ipl()); + (void) new OptFlexUnary(TestTag::sweep,6,2,7,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFixPUnary(p30,0,ipba.ipl()); - (void) new ManFixPUnary(p30,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFixPUnary(p30,0,ipba.ipl()); - (void) new OptFixPUnary(p30,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(8,0,9,0,ipba.ipl()); - (void) new ManFlexUnary(8,0,9,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFlexUnary(8,0,9,0,ipba.ipl()); - (void) new OptFlexUnary(8,0,9,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFixPUnary(TestTag::sweep,p30,0,ipba.ipl()); + (void) new ManFixPUnary(TestTag::sweep,p30,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFixPUnary(TestTag::sweep,p30,0,ipba.ipl()); + (void) new OptFixPUnary(TestTag::sweep,p30,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,8,0,9,0,ipba.ipl()); + (void) new ManFlexUnary(TestTag::sweep,8,0,9,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFlexUnary(TestTag::sweep,8,0,9,0,ipba.ipl()); + (void) new OptFlexUnary(TestTag::sweep,8,0,9,Gecode::Int::Limits::min,ipba.ipl()); } } }; diff --git a/test/nogoods.cpp b/test/nogoods.cpp index 14c52f5984..80baab57ab 100644 --- a/test/nogoods.cpp +++ b/test/nogoods.cpp @@ -221,13 +221,11 @@ namespace Test { return s.str(); } /// Initialize test - NoGoods(ValBranch vb0, unsigned int t0, bool a0, bool n0) + NoGoods(TestTags tags, ValBranch vb0, + unsigned int t0, bool a0, bool n0) : Base("NoGoods::"+Model::name()+"::"+Model::val(vb0)+"::"+str(t0)+ - "::"+(a0 ? "+" : "-")+"::"+(n0 ? "+" : "-")), - vb(vb0), t(t0), a(a0), n(n0) { - if (Model::name() == "Queens") - add_tags(TestTag::check); - } + "::"+(a0 ? "+" : "-")+"::"+(n0 ? "+" : "-"),tags), + vb(vb0), t(t0), a(a0), n(n0) {} /// Run test virtual bool run(void) { Model* m = new Model(vb,a,n); @@ -277,17 +275,18 @@ namespace Test { bool n = false; do { for (unsigned int t = 1; t<=4; t++) { - (void) new NoGoods(INT_VAL_MIN(),t,a,n); - (void) new NoGoods(INT_VAL_MAX(),t,a,n); - (void) new NoGoods(INT_VAL_SPLIT_MIN(),t,a,n); - (void) new NoGoods(INT_VAL_SPLIT_MAX(),t,a,n); - (void) new NoGoods(INT_VALUES_MIN(),t,a,n); - (void) new NoGoods(INT_VALUES_MAX(),t,a,n); + TestTags queens(TestTag::normal,TestTag::check); + (void) new NoGoods(queens,INT_VAL_MIN(),t,a,n); + (void) new NoGoods(queens,INT_VAL_MAX(),t,a,n); + (void) new NoGoods(queens,INT_VAL_SPLIT_MIN(),t,a,n); + (void) new NoGoods(queens,INT_VAL_SPLIT_MAX(),t,a,n); + (void) new NoGoods(queens,INT_VALUES_MIN(),t,a,n); + (void) new NoGoods(queens,INT_VALUES_MAX(),t,a,n); #ifdef GECODE_HAS_SET_VARS - (void) new NoGoods(SET_VAL_MIN_INC(),t,a,n); - (void) new NoGoods(SET_VAL_MIN_EXC(),t,a,n); - (void) new NoGoods(SET_VAL_MAX_INC(),t,a,n); - (void) new NoGoods(SET_VAL_MAX_EXC(),t,a,n); + (void) new NoGoods(TestTag::normal,SET_VAL_MIN_INC(),t,a,n); + (void) new NoGoods(TestTag::normal,SET_VAL_MIN_EXC(),t,a,n); + (void) new NoGoods(TestTag::normal,SET_VAL_MAX_INC(),t,a,n); + (void) new NoGoods(TestTag::normal,SET_VAL_MAX_EXC(),t,a,n); #endif } n = !n; diff --git a/test/search.cpp b/test/search.cpp index 2898150f96..ef5671001a 100644 --- a/test/search.cpp +++ b/test/search.cpp @@ -386,11 +386,16 @@ namespace Test { return ""; } /// Initialize test - Test(const std::string& s, + Test(TestTags tags, const std::string& s, HowToBranch _htb1, HowToBranch _htb2, HowToBranch _htb3, HowToConstrain _htc=HTC_NONE) - : Base("Search::"+s), + : Base("Search::"+s,tags), htb1(_htb1), htb2(_htb2), htb3(_htb3), htc(_htc) {} + /// Initialize a normal test + Test(const std::string& s, + HowToBranch _htb1, HowToBranch _htb2, HowToBranch _htb3, + HowToConstrain _htc=HTC_NONE) + : Test(TestTag::normal,s,_htb1,_htb2,_htb3,_htc) {} }; /// Randomly resize a live leaf engine from another thread @@ -754,22 +759,13 @@ namespace Test { unsigned int t; public: /// Initialize test - DFS(HowToBranch htb1, HowToBranch htb2, HowToBranch htb3, + DFS(TestTags tags, + HowToBranch htb1, HowToBranch htb2, HowToBranch htb3, unsigned int c_d0, unsigned int a_d0, unsigned int t0) - : Test("DFS::"+Model::name()+"::"+ + : Test(tags,"DFS::"+Model::name()+"::"+ str(htb1)+"::"+str(htb2)+"::"+str(htb3)+"::"+ str(c_d0)+"::"+str(a_d0)+"::"+str(t0), - htb1,htb2,htb3), c_d(c_d0), a_d(a_d0), t(t0) { - if (Model::name().compare(0,3,"Sol") == 0) - tags(TestTag::sweep); - if ((Model::name() == "Sol") && - (htb1 == HTB_BINARY) && (htb2 == HTB_NARY) && - (htb3 == HTB_BINARY) && (c_d0 == 1) && - (a_d0 == 1) && (t0 == 1)) { - tags(TestTag::normal); - add_tags(TestTag::check); - } - } + htb1,htb2,htb3), c_d(c_d0), a_d(a_d0), t(t0) {} /// Run test virtual bool run(void) { Model* m = new Model(htb1,htb2,htb3); @@ -854,21 +850,13 @@ namespace Test { unsigned int t; public: /// Initialize test - BAB(HowToConstrain htc, + BAB(TestTags tags, HowToConstrain htc, HowToBranch htb1, HowToBranch htb2, HowToBranch htb3, unsigned int c_d0, unsigned int a_d0, unsigned int t0) - : Test("BAB::"+Model::name()+"::"+str(htc)+"::"+ + : Test(tags,"BAB::"+Model::name()+"::"+str(htc)+"::"+ str(htb1)+"::"+str(htb2)+"::"+str(htb3)+"::"+ str(c_d0)+"::"+str(a_d0)+"::"+str(t0), - htb1,htb2,htb3,htc), c_d(c_d0), a_d(a_d0), t(t0) { - if (Model::name().compare(0,3,"Sol") == 0) - tags(TestTag::sweep); - if ((Model::name() == "Sol") && (htc == HTC_BAL_GR) && - (htb1 == HTB_BINARY) && (htb2 == HTB_BINARY) && - (htb3 == HTB_BINARY) && (c_d0 == 1) && - (a_d0 == 1) && (t0 == 1)) - tags(TestTag::normal); - } + htb1,htb2,htb3,htc), c_d(c_d0), a_d(a_d0), t(t0) {} /// Run test virtual bool run(void) { Model* m = new Model(htb1,htb2,htb3,htc); @@ -1173,12 +1161,21 @@ namespace Test { for (BranchTypes htb2; htb2(); ++htb2) for (BranchTypes htb3; htb3(); ++htb3) (void) new DFS - (htb1.htb(),htb2.htb(),htb3.htb(),c_d, a_d, t); - new DFS(HTB_NONE, HTB_NONE, HTB_NONE, + ((htb1.htb() == HTB_BINARY) && + (htb2.htb() == HTB_NARY) && + (htb3.htb() == HTB_BINARY) && + (c_d == 1) && (a_d == 1) && (t == 1) + ? TestTags(TestTag::normal,TestTag::check) + : TestTags(TestTag::sweep), + htb1.htb(),htb2.htb(),htb3.htb(),c_d,a_d,t); + new DFS(TestTag::normal, + HTB_NONE, HTB_NONE, HTB_NONE, c_d, a_d, t); - new DFS(HTB_NONE, HTB_NONE, HTB_NONE, + new DFS(TestTag::sweep, + HTB_NONE, HTB_NONE, HTB_NONE, c_d, a_d, t); - new DFS(HTB_NONE, HTB_NONE, HTB_NONE, + new DFS(TestTag::sweep, + HTB_NONE, HTB_NONE, HTB_NONE, c_d, a_d, t); } @@ -1202,15 +1199,25 @@ namespace Test { for (BranchTypes htb2; htb2(); ++htb2) for (BranchTypes htb3; htb3(); ++htb3) { (void) new BAB - (htc.htc(),htb1.htb(),htb2.htb(),htb3.htb(), + ((htc.htc() == HTC_BAL_GR) && + (htb1.htb() == HTB_BINARY) && + (htb2.htb() == HTB_BINARY) && + (htb3.htb() == HTB_BINARY) && + (c_d == 1) && (a_d == 1) && (t == 1) + ? TestTags(TestTag::normal) + : TestTags(TestTag::sweep), + htc.htc(),htb1.htb(),htb2.htb(),htb3.htb(), c_d,a_d,t); } (void) new BAB - (HTC_NONE,HTB_NONE,HTB_NONE,HTB_NONE,c_d,a_d,t); + (TestTag::normal,HTC_NONE,HTB_NONE,HTB_NONE,HTB_NONE, + c_d,a_d,t); (void) new BAB - (HTC_NONE,HTB_NONE,HTB_NONE,HTB_NONE,c_d,a_d,t); + (TestTag::sweep,HTC_NONE,HTB_NONE,HTB_NONE,HTB_NONE, + c_d,a_d,t); (void) new BAB - (HTC_NONE,HTB_NONE,HTB_NONE,HTB_NONE,c_d,a_d,t); + (TestTag::sweep,HTC_NONE,HTB_NONE,HTB_NONE,HTB_NONE, + c_d,a_d,t); } // Restart-based search for (unsigned int t=1; t<=4; t++) { diff --git a/test/set/channel.cpp b/test/set/channel.cpp index cd4f32727a..1ea3f0ed4c 100644 --- a/test/set/channel.cpp +++ b/test/set/channel.cpp @@ -137,10 +137,9 @@ namespace Test { namespace Set { int isize; public: /// Create and register test - ChannelBool(const char* t, const IntSet& d, int _isize) - : SetTest(std::string(t) == "Channel::Bool::1" - ? TestTag::normal : TestTag::sweep, - t,1,d,false,_isize), isize(_isize) {} + ChannelBool(TestTags tags, const char* t, + const IntSet& d, int _isize) + : SetTest(tags,t,1,d,false,_isize), isize(_isize) {} /// %Test whether \a x is solution virtual bool solution(const SetAssignment& x) const { for (int i=0; i Date: Mon, 28 Sep 2026 19:59:59 +0200 Subject: [PATCH 11/23] Export public test tags from shared harness --- test/package/public-test-component/consumer-smoke.cpp | 2 ++ test/public-runner-smoke.cpp | 2 +- test/test.hh | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/package/public-test-component/consumer-smoke.cpp b/test/package/public-test-component/consumer-smoke.cpp index 8bcdf80813..bffa693887 100644 --- a/test/package/public-test-component/consumer-smoke.cpp +++ b/test/package/public-test-component/consumer-smoke.cpp @@ -72,5 +72,7 @@ class FloatEqualityTest final : public ::Test::Float::Test { } // namespace int main(int argc, char* argv[]) { + if (Test::TestTags::all().empty()) + return 1; return Test::run_registered_tests(argc, argv); } diff --git a/test/public-runner-smoke.cpp b/test/public-runner-smoke.cpp index 1a8110588b..ae09f3164d 100644 --- a/test/public-runner-smoke.cpp +++ b/test/public-runner-smoke.cpp @@ -71,7 +71,7 @@ namespace { int replay_runs = 0; class ReplaySmokeTest : public Test::Base { public: - ReplaySmokeTest(void) : Test::Base("Smoke::Replay") {} + ReplaySmokeTest(void) : Test::Base("Smoke::Replay", Test::TestTags()) {} bool run(void) override { if (++replay_runs == 1) { // Leave a state above the seed setter's modulus for the next iteration. diff --git a/test/test.hh b/test/test.hh index 00b30ed9e6..3eecfb79e2 100755 --- a/test/test.hh +++ b/test/test.hh @@ -102,7 +102,7 @@ namespace Test { }; /// Set of test tags - class TestTags { + class GECODE_TEST_EXPORT TestTags { private: /// Bit mask for tags unsigned int _mask; From 5dac10eb8e4a093e0cf0dbab054d4f3af1ff842c Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Sun, 4 Oct 2026 14:38:07 +0200 Subject: [PATCH 12/23] Clarify tag selection and remove obsolete test helpers --- cmake/VerifyTestSelection.cmake | 24 ------------------------ test/test.hh | 2 -- test/test.hpp | 3 --- 3 files changed, 29 deletions(-) delete mode 100644 cmake/VerifyTestSelection.cmake diff --git a/cmake/VerifyTestSelection.cmake b/cmake/VerifyTestSelection.cmake deleted file mode 100644 index 6991a45e7d..0000000000 --- a/cmake/VerifyTestSelection.cmake +++ /dev/null @@ -1,24 +0,0 @@ -if(NOT DEFINED TEST_EXECUTABLE OR NOT DEFINED REQUIRED_TESTS) - message(FATAL_ERROR "TEST_EXECUTABLE and REQUIRED_TESTS are required") -endif() - -execute_process( - COMMAND "${TEST_EXECUTABLE}" -list - RESULT_VARIABLE list_result - OUTPUT_VARIABLE registered_tests - ERROR_VARIABLE list_error) -if(NOT list_result EQUAL 0) - message(FATAL_ERROR - "Could not list registered Gecode tests (${list_result}): ${list_error}") -endif() - -string(REPLACE "\r\n" "\n" registered_tests "${registered_tests}") -string(REPLACE "\r" "\n" registered_tests "${registered_tests}") -set(registered_tests "\n${registered_tests}\n") -foreach(required_test IN LISTS REQUIRED_TESTS) - string(FIND "${registered_tests}" "\n${required_test}\n" test_position) - if(test_position EQUAL -1) - message(FATAL_ERROR - "Required check test is not registered: ${required_test}") - endif() -endforeach() diff --git a/test/test.hh b/test/test.hh index 3eecfb79e2..470ea8f538 100755 --- a/test/test.hh +++ b/test/test.hh @@ -106,8 +106,6 @@ namespace Test { private: /// Bit mask for tags unsigned int _mask; - /// Initialize from raw bit mask \a m - explicit TestTags(unsigned int m); public: /// Initialize with no tags TestTags(void); diff --git a/test/test.hpp b/test/test.hpp index 120a260c7e..08a9894cd0 100755 --- a/test/test.hpp +++ b/test/test.hpp @@ -38,9 +38,6 @@ namespace Test { * */ inline - TestTags::TestTags(unsigned int m) - : _mask(m) {} - inline TestTags::TestTags(void) : _mask(0) {} inline From 9264381e874f47c63650faef8ee984519d4164da Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Mon, 5 Oct 2026 07:58:50 +0200 Subject: [PATCH 13/23] Exercise substantive arithmetic paths in the normal test suite --- test/float/arithmetic.cpp | 30 ++++++++++++++++++++---------- test/int/arithmetic.cpp | 38 ++++++++++++++++++++++---------------- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/test/float/arithmetic.cpp b/test/float/arithmetic.cpp index 21c99a7f26..644866993e 100755 --- a/test/float/arithmetic.cpp +++ b/test/float/arithmetic.cpp @@ -1032,8 +1032,10 @@ namespace Test { namespace Float { class MinXYZ : public Test { public: /// Create and register test - MinXYZ(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Min::Bin::XYZ::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} + MinXYZ(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, Gecode::FloatNum st) + : Test(tags,"Arithmetic::Min::Bin::XYZ::"+s, + 3,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(x[0],x[1]), x[2]); @@ -1117,8 +1119,10 @@ namespace Test { namespace Float { class MaxXYZ : public Test { public: /// Create and register test - MaxXYZ(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Max::Bin::XYZ::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} + MaxXYZ(TestTags tags, const std::string& s, + const Gecode::FloatVal& d, Gecode::FloatNum st) + : Test(tags,"Arithmetic::Max::Bin::XYZ::"+s, + 3,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(x[0],x[1]), x[2]); @@ -1424,9 +1428,12 @@ namespace Test { namespace Float { AbsXX abs_xx_b(TestTag::sweep,"B",b,step); AbsXX abs_xx_c(TestTag::sweep,"C",c,step); - MinXYZ min_xyz_a("A",a,step); - MinXYZ min_xyz_b("B",b,step); - MinXYZ min_xyz_c("C",c,step); + MinXYZ min_xyz_normal( + TestTag::normal,"Normal",Gecode::FloatVal(-1,1),1.0); + + MinXYZ min_xyz_a(TestTag::sweep,"A",a,step); + MinXYZ min_xyz_b(TestTag::sweep,"B",b,step); + MinXYZ min_xyz_c(TestTag::sweep,"C",c,step); MinXXY min_xxy_a("A",a,step); MinXXY min_xxy_b("B",b,step); @@ -1444,9 +1451,12 @@ namespace Test { namespace Float { MinXXX min_xxx_b(TestTag::sweep,"B",b,step); MinXXX min_xxx_c(TestTag::sweep,"C",c,step); - MaxXYZ max_xyz_a("A",a,step); - MaxXYZ max_xyz_b("B",b,step); - MaxXYZ max_xyz_c("C",c,step); + MaxXYZ max_xyz_normal( + TestTag::normal,"Normal",Gecode::FloatVal(-1,1),1.0); + + MaxXYZ max_xyz_a(TestTag::sweep,"A",a,step); + MaxXYZ max_xyz_b(TestTag::sweep,"B",b,step); + MaxXYZ max_xyz_c(TestTag::sweep,"C",c,step); MaxXXY max_xxy_a("A",a,step); MaxXXY max_xxy_b("B",b,step); diff --git a/test/int/arithmetic.cpp b/test/int/arithmetic.cpp index d83eb87aec..a3f6c63c38 100644 --- a/test/int/arithmetic.cpp +++ b/test/int/arithmetic.cpp @@ -2182,9 +2182,9 @@ namespace Test { namespace Int { int n; public: /// Create and register test - PowXY(const std::string& s, int n0, const Gecode::IntSet& d, - Gecode::IntPropLevel ipl) - : Test(TestTag::sweep, + PowXY(TestTags tags, const std::string& s, int n0, + const Gecode::IntSet& d, Gecode::IntPropLevel ipl) + : Test(tags, "Arithmetic::Pow::XY::"+str(n0)+"::"+str(ipl)+"::"+s, 2,d,false,ipl), n(n0) {} /// %Test whether \a x is solution @@ -2301,9 +2301,9 @@ namespace Test { namespace Int { /// Floor public: /// Create and register test - NrootXY(const std::string& s, int n0, const Gecode::IntSet& d, - Gecode::IntPropLevel ipl) - : Test(TestTag::sweep, + NrootXY(TestTags tags, const std::string& s, int n0, + const Gecode::IntSet& d, Gecode::IntPropLevel ipl) + : Test(tags, "Arithmetic::Nroot::XY::"+str(n0)+"::"+str(ipl)+"::"+s, 2,d,false,ipl), n(n0) {} /// %Test whether \a x is solution @@ -3161,10 +3161,13 @@ namespace Test { namespace Int { (void) new SqrXX("C",c,ipls.ipl()); for (int n=0; n<=6; n++) { - (void) new PowXY("A",n,a,ipls.ipl()); - (void) new PowXY("B",n,b,ipls.ipl()); - (void) new PowXY("C",n,c,ipls.ipl()); - (void) new PowXY("D",n,d,ipls.ipl()); + TestTags distinct_tags = (n == 3) && + (ipls.ipl() == Gecode::IPL_BND) + ? TestTag::normal : TestTag::sweep; + (void) new PowXY(TestTag::sweep,"A",n,a,ipls.ipl()); + (void) new PowXY(TestTag::sweep,"B",n,b,ipls.ipl()); + (void) new PowXY(distinct_tags,"C",n,c,ipls.ipl()); + (void) new PowXY(TestTag::sweep,"D",n,d,ipls.ipl()); TestTags tags = (n == 0) && (ipls.ipl() == Gecode::IPL_BND) ? TestTag::normal : TestTag::sweep; @@ -3175,10 +3178,13 @@ namespace Test { namespace Int { } for (int n=1; n<=6; n++) { - (void) new NrootXY("A",n,a,ipls.ipl()); - (void) new NrootXY("B",n,b,ipls.ipl()); - (void) new NrootXY("C",n,c,ipls.ipl()); - (void) new NrootXY("D",n,d,ipls.ipl()); + TestTags distinct_tags = (n == 3) && + (ipls.ipl() == Gecode::IPL_BND) + ? TestTag::normal : TestTag::sweep; + (void) new NrootXY(TestTag::sweep,"A",n,a,ipls.ipl()); + (void) new NrootXY(TestTag::sweep,"B",n,b,ipls.ipl()); + (void) new NrootXY(distinct_tags,"C",n,c,ipls.ipl()); + (void) new NrootXY(TestTag::sweep,"D",n,d,ipls.ipl()); TestTags tags = (n == 1) && (ipls.ipl() == Gecode::IPL_BND) ? TestTag::normal : TestTag::sweep; @@ -3189,9 +3195,9 @@ namespace Test { namespace Int { } for (int n=30; n<=34; n++) { - (void) new PowXY("C",n,c,ipls.ipl()); + (void) new PowXY(TestTag::sweep,"C",n,c,ipls.ipl()); (void) new PowXX(TestTag::sweep,"C",n,c,ipls.ipl()); - (void) new NrootXY("C",n,c,ipls.ipl()); + (void) new NrootXY(TestTag::sweep,"C",n,c,ipls.ipl()); (void) new NrootXX(TestTag::sweep,"C",n,c,ipls.ipl()); } From dbba4c344749ebecd6980c6a318f0d9f3256703a Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Thu, 8 Oct 2026 16:56:48 +0200 Subject: [PATCH 14/23] Preserve stacked tag contracts and worker-control check coverage --- docs/cmake-build.md | 19 ++----------------- test/search.cpp | 8 ++++---- test/test.hh | 11 ++++++++++- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/docs/cmake-build.md b/docs/cmake-build.md index 95fc142e7f..065110d437 100644 --- a/docs/cmake-build.md +++ b/docs/cmake-build.md @@ -91,23 +91,8 @@ cmake --build build --target check-sweep `check-normal` runs the normal test suite. `check-sweep` runs tests tagged as heavy sweep tests and is intended for deliberate, longer-running validation. -The test runner can also be invoked directly with tags: - -```bash -gecode-test -tag check -gecode-test -tag normal -gecode-test -tag sweep -gecode-test -tag normal -tag sweep -gecode-test -tag all -``` - -With no `-tag` option, the runner does not restrict tests by tag. Repeated tags -form a union, while tag and name filters intersect. `-tag all` explicitly -selects every known tag. - -Use `gecode-test -list-tags` to list known tags and -`gecode-test -list-with-tags` to inspect test assignments. Listing always shows -all registered tests, regardless of selection filters. +Use `gecode-test -help` for runner options and `gecode-test -list-with-tags` +to inspect test assignments. ## Build Conventions and Key Options diff --git a/test/search.cpp b/test/search.cpp index ef5671001a..d3ecaed43b 100644 --- a/test/search.cpp +++ b/test/search.cpp @@ -495,7 +495,7 @@ namespace Test { return caught && (live == (clone ? 1 : 0)); } public: - PBSConstructionFailure(void) : Base("Search::PBS::ConstructionFailure") {} + PBSConstructionFailure(void) : Base("Search::PBS::ConstructionFailure", TestTags(TestTag::normal,TestTag::check)) {} bool run(void) override { for (unsigned int threads : {1U,4U}) for (bool clone : {false,true}) @@ -586,7 +586,7 @@ namespace Test { } public: WorkerControlSequentialPause(void) - : Base("Search::WorkerControl::SequentialPause") {} + : Base("Search::WorkerControl::SequentialPause", TestTags(TestTag::normal,TestTag::check)) {} bool run(void) override { #ifdef GECODE_HAS_THREADS return check(0U) && check(1U) && @@ -613,7 +613,7 @@ namespace Test { return false; } public: - WorkerControlAPI(void) : Base("Search::WorkerControl::API") {} + WorkerControlAPI(void) : Base("Search::WorkerControl::API", TestTags(TestTag::normal,TestTag::check)) {} bool run(void) override { using Gecode::Search::WorkerControl; WorkerControl empty; @@ -685,7 +685,7 @@ namespace Test { class WorkerControlPBSPause : public Base { public: WorkerControlPBSPause(void) - : Base("Search::WorkerControl::PBS::Pause") {} + : Base("Search::WorkerControl::PBS::Pause", TestTags(TestTag::normal,TestTag::check)) {} bool run(void) override { bool ok = true; // A sequential portfolio must reject assets that could block its round. diff --git a/test/test.hh b/test/test.hh index 470ea8f538..5dd9e8c46f 100755 --- a/test/test.hh +++ b/test/test.hh @@ -196,7 +196,10 @@ namespace Test { public: /// Create and register a normal test with name \a s Base(std::string s); - /// Create and register test with name \a s and tags \a t + /** \brief Create and register test with name \a s and tags \a t + * + * The supplied tags determine membership independently of the name. + */ Base(std::string s, TestTags t); /// Sort tests alphabetically static void sort(void); @@ -245,6 +248,12 @@ namespace Test { * reports provide a -replay state and exact -test name. Replay runs that * test once on one thread, starting from the failing iteration's state. * -log prints the buffered log on failure and requires one thread. + * + * Repeated -tag options select the union of their tags. With no -tag, + * all tests are eligible, including tests without tags; -tag all selects + * tests with at least one known tag. Name and tag filters must both match. + * -list and -list-with-tags list every registered test, ignoring -test, + * -tag, and -start. * \relates Test::Base */ GECODE_TEST_EXPORT int run_registered_tests(int argc, char* argv[]); From ca797c1539ac1c07a70cfa2a3dc54cc71f23ceb7 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Fri, 9 Oct 2026 08:22:42 +0200 Subject: [PATCH 15/23] Keep NFA regression tests in the tagged check selection --- test/int/extensional.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/int/extensional.cpp b/test/int/extensional.cpp index 7099020260..53dc0a1513 100755 --- a/test/int/extensional.cpp +++ b/test/int/extensional.cpp @@ -567,7 +567,8 @@ namespace Test { namespace Int { public: /// Create and register test RegRandomNFADifferential(unsigned int seed) - : Test("Extensional::Reg::Sparse::RandomNFADifferential::" + + : Test(TestTags(TestTag::normal,TestTag::check), + "Extensional::Reg::Sparse::RandomNFADifferential::" + Test::str(static_cast(seed)), 5,0,n_symbols-1,false,Gecode::IPL_DOM) { unsigned int random = seed; @@ -640,7 +641,8 @@ namespace Test { namespace Int { public: /// Create and register test RegNFAPrefix(bool b) - : Test("Extensional::Reg::Sparse::NFAPrefix::" + + : Test(TestTags(TestTag::normal,TestTag::check), + "Extensional::Reg::Sparse::NFAPrefix::" + std::string(b ? "Bool" : "Int"), 5,0,1,false,Gecode::IPL_DOM), boolean(b) {} /// %Test whether \a x is a solution From 3659fc1b3e7835bb2271123b0a1e75b980745506 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Fri, 9 Oct 2026 09:00:48 +0200 Subject: [PATCH 16/23] Remove redundant tag-selection state and unused tag removal API --- test/test.cpp | 3 +-- test/test.hh | 4 ---- test/test.hpp | 6 +----- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/test/test.cpp b/test/test.cpp index cefdf41797..0ce1b5a68a 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -267,7 +267,6 @@ namespace Test { exit(EXIT_FAILURE); } testtags.add(tag); - use_testtags = true; } else if (!strcmp(argv[i],"-start")) { if (++i == argc) goto missing; start_from = argv[i]; @@ -355,7 +354,7 @@ namespace Test { } bool Options::is_test_tags_matching(TestTags tags) const { - return !use_testtags || tags.overlaps(testtags); + return testtags.empty() || tags.overlaps(testtags); } /// Run a single test, returning true iff the test succeeded diff --git a/test/test.hh b/test/test.hh index 5dd9e8c46f..21369afad0 100755 --- a/test/test.hh +++ b/test/test.hh @@ -121,8 +121,6 @@ namespace Test { bool overlaps(TestTags t) const; /// Add tags \a t void add(TestTags t); - /// Remove tags \a t - void remove(TestTags t); }; /// Commandline options @@ -150,8 +148,6 @@ namespace Test { std::vector > testpat; /// Tags to test against TestTags testtags; - /// Whether test tags have been requested - bool use_testtags; /// Name of first test to start with const char* start_from; /// Whether to list all tests diff --git a/test/test.hpp b/test/test.hpp index 08a9894cd0..9ef24cc0f0 100755 --- a/test/test.hpp +++ b/test/test.hpp @@ -59,10 +59,6 @@ namespace Test { TestTags::add(TestTags t) { _mask |= t._mask; } - inline void - TestTags::remove(TestTags t) { - _mask &= ~t._mask; - } /* * Commandline options @@ -71,7 +67,7 @@ namespace Test { inline Options::Options(void) : threads(1), seed(0), replay(false), iter(defiter), fixprob(deffixprob), - stop(true), log(false), testpat(), testtags(), use_testtags(false), + stop(true), log(false), testpat(), testtags(), start_from(nullptr), list(false), list_tags(false), list_with_tags(false) {} From c6504e6b0ec88765fe799a4cb5b446e096f715b6 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Fri, 9 Oct 2026 14:54:30 +0200 Subject: [PATCH 17/23] Name the standard suite and add common test tag presets --- CMakeLists.txt | 16 ++-- Makefile.in | 6 +- changelog.in | 4 +- docs/cmake-build.md | 4 +- test/branch.cpp | 2 +- test/branch/set.cpp | 4 +- test/flatzinc.cpp | 8 +- test/flatzinc/blackbox.cpp | 40 ++++---- test/flatzinc/magicsq_3.cpp | 2 +- test/flatzinc/magicsq_4.cpp | 2 +- test/flatzinc/magicsq_5.cpp | 2 +- test/flatzinc/oss.cpp | 2 +- test/flatzinc/packing.cpp | 2 +- test/flatzinc/radiation.cpp | 2 +- test/flatzinc/steiner_triples.cpp | 2 +- test/flatzinc/template_design.cpp | 2 +- test/flatzinc/tenpenki_1.cpp | 2 +- test/flatzinc/tenpenki_2.cpp | 2 +- test/flatzinc/tenpenki_3.cpp | 2 +- test/flatzinc/tenpenki_4.cpp | 2 +- test/flatzinc/tenpenki_5.cpp | 2 +- test/flatzinc/tenpenki_6.cpp | 2 +- test/flatzinc/timetabling.cpp | 2 +- test/flatzinc/trucking.cpp | 2 +- test/float.hpp | 4 +- test/float/arithmetic.cpp | 152 +++++++++++++++--------------- test/float/linear.cpp | 42 ++++----- test/float/mm-lin.cpp | 2 +- test/float/transcendental.cpp | 48 +++++----- test/float/trigonometric.cpp | 60 ++++++------ test/int.hpp | 8 +- test/int/arithmetic.cpp | 56 +++++------ test/int/channel.cpp | 14 +-- test/int/circuit.cpp | 10 +- test/int/cumulative.cpp | 10 +- test/int/distinct.cpp | 12 +-- test/int/extensional.cpp | 16 ++-- test/int/gcc.cpp | 12 +-- test/int/linear.cpp | 52 +++++----- test/int/mm-lin.cpp | 8 +- test/int/no-overlap.cpp | 20 ++-- test/int/nvalues.cpp | 4 +- test/int/rel.cpp | 16 ++-- test/int/unary.cpp | 94 +++++++++--------- test/nogoods.cpp | 10 +- test/public-runner-smoke.cpp | 16 ++-- test/search.cpp | 30 +++--- test/set.hh | 2 +- test/set/channel.cpp | 12 +-- test/set/dom.cpp | 12 +-- test/set/element.cpp | 16 ++-- test/set/exec.cpp | 2 +- test/set/mm-set.cpp | 30 +++--- test/set/precede.cpp | 8 +- test/set/rel-op-const.cpp | 8 +- test/set/rel-op.cpp | 6 +- test/set/rel.cpp | 2 +- test/set/sequence.cpp | 4 +- test/test.cpp | 4 +- test/test.hh | 10 +- test/test.hpp | 12 +++ 61 files changed, 479 insertions(+), 461 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e3b7afc17..01b980c7be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1532,12 +1532,12 @@ if(BUILD_TESTING) $ ${GECODE_CHECK_ARGS} DEPENDS ${GECODE_CHECK_DEPENDS} USES_TERMINAL) - add_custom_target(check-normal + add_custom_target(check-standard COMMAND ${CMAKE_COMMAND} -E env GECODE_TEST_BLACKBOX_EXEC=$ GECODE_TEST_BLACKBOX_DLL=$ GECODE_TEST_BLACKBOX_LOG=${GECODE_TEST_BLACKBOX_LOG} - $ -tag normal + $ -tag standard DEPENDS ${GECODE_CHECK_DEPENDS} USES_TERMINAL) add_custom_target(check-sweep @@ -1553,8 +1553,8 @@ if(BUILD_TESTING) COMMAND $ ${GECODE_CHECK_ARGS} DEPENDS ${GECODE_CHECK_DEPENDS} USES_TERMINAL) - add_custom_target(check-normal - COMMAND $ -tag normal + add_custom_target(check-standard + COMMAND $ -tag standard DEPENDS gecode-test USES_TERMINAL) add_custom_target(check-sweep @@ -1578,16 +1578,16 @@ if(BUILD_TESTING) message(WARNING "Skipping gecode-test/check targets because required modules are disabled") add_custom_target(check COMMAND ${CMAKE_COMMAND} -E echo "Skipping check target because required modules are disabled") - add_custom_target(check-normal - COMMAND ${CMAKE_COMMAND} -E echo "Skipping check-normal target because required modules are disabled") + add_custom_target(check-standard + COMMAND ${CMAKE_COMMAND} -E echo "Skipping check-standard target because required modules are disabled") add_custom_target(check-sweep COMMAND ${CMAKE_COMMAND} -E echo "Skipping check-sweep target because required modules are disabled") endif() else() add_custom_target(check COMMAND ${CMAKE_COMMAND} -E echo "Skipping check target because BUILD_TESTING is OFF") - add_custom_target(check-normal - COMMAND ${CMAKE_COMMAND} -E echo "Skipping check-normal target because BUILD_TESTING is OFF") + add_custom_target(check-standard + COMMAND ${CMAKE_COMMAND} -E echo "Skipping check-standard target because BUILD_TESTING is OFF") add_custom_target(check-sweep COMMAND ${CMAKE_COMMAND} -E echo "Skipping check-sweep target because BUILD_TESTING is OFF") endif() diff --git a/Makefile.in b/Makefile.in index 2d595117d0..62bd48f92c 100755 --- a/Makefile.in +++ b/Makefile.in @@ -1518,9 +1518,9 @@ check: test $(BLACKBOXCHECKENV) $(RUNENVIRONMENT) \ $(TESTEXE) -iter 2 -threads 0 -fixprob 1 -tag check -# The normal test suite without sweep tests -check-normal: test - $(BLACKBOXCHECKENV) $(RUNENVIRONMENT) $(TESTEXE) -tag normal +# The standard test suite without sweep tests +check-standard: test + $(BLACKBOXCHECKENV) $(RUNENVIRONMENT) $(TESTEXE) -tag standard # Really heavy sweep tests check-sweep: test diff --git a/changelog.in b/changelog.in index 38c76574ff..f66ceaa446 100755 --- a/changelog.in +++ b/changelog.in @@ -134,8 +134,8 @@ Module: test What: new Rank: major [DESCRIPTION] -Add self-declared check, normal, and sweep tags to the public test harness. -The standard check targets use a focused integrity selection, while normal +Add self-declared check, standard, and sweep tags to the public test harness. +The standard check targets use a focused integrity selection, while standard testing retains broad coverage without the exhaustive multi-hour sweeps. [ENTRY] diff --git a/docs/cmake-build.md b/docs/cmake-build.md index 065110d437..23f9677791 100644 --- a/docs/cmake-build.md +++ b/docs/cmake-build.md @@ -84,11 +84,11 @@ cmake --build build --target check Two additional targets expose broader tag-based suites: ```bash -cmake --build build --target check-normal +cmake --build build --target check-standard cmake --build build --target check-sweep ``` -`check-normal` runs the normal test suite. `check-sweep` runs tests tagged as +`check-standard` runs the standard test suite. `check-sweep` runs tests tagged as heavy sweep tests and is intended for deliberate, longer-running validation. Use `gecode-test -help` for runner options and `gecode-test -list-with-tags` diff --git a/test/branch.cpp b/test/branch.cpp index 23a63bc86f..31931d5459 100644 --- a/test/branch.cpp +++ b/test/branch.cpp @@ -738,7 +738,7 @@ namespace Test { namespace Branch { } SetTest::SetTest(const std::string& s, int a, const Gecode::IntSet& d) - : SetTest(TestTag::normal,s,a,d) { + : SetTest(TestTags::standard(),s,a,d) { } bool diff --git a/test/branch/set.cpp b/test/branch/set.cpp index de3494bc8f..aac3ae0e3a 100644 --- a/test/branch/set.cpp +++ b/test/branch/set.cpp @@ -57,8 +57,8 @@ namespace Test { namespace Branch { const int v_sparse[6] = {-100,-10,0,10,100,1000}; Gecode::IntSet d_sparse(v_sparse,6); - Set d_3(TestTag::normal,"Dense::3",d_dense,3); - Set s_3(TestTag::sweep,"Sparse::3",d_sparse,3); + Set d_3(TestTags::standard(),"Dense::3",d_dense,3); + Set s_3(TestTags::sweep(),"Sparse::3",d_sparse,3); } }} diff --git a/test/flatzinc.cpp b/test/flatzinc.cpp index ee98085d94..c1845f8522 100755 --- a/test/flatzinc.cpp +++ b/test/flatzinc.cpp @@ -82,7 +82,7 @@ namespace Test { namespace FlatZinc { public: GistStatisticsMode(void) : Base("FlatZinc::Options::GistStatisticsMode", - TestTags(TestTag::normal,TestTag::check)) {} + TestTags::check()) {} virtual bool run(void) { return @@ -97,7 +97,7 @@ namespace Test { namespace FlatZinc { #ifndef GECODE_HAS_GIST /// Verify that unavailable Gist mode is rejected instead of running search. FlatZincErrorTest gist_unavailable( - TestTags(TestTag::normal,TestTag::check), + TestTags::check(), "Options::GistUnavailable", "var 1..1: x :: output_var;\nsolve satisfy;\n", {"-mode", "gist", "-s"}, @@ -110,7 +110,7 @@ namespace Test { namespace FlatZinc { const std::string& expected, bool allSolutions, std::vector cmdlineOpt, OutputCheck check, BeforeRun before) - : FlatZincTest(TestTag::normal, name, source, expected, allSolutions, + : FlatZincTest(TestTags::standard(), name, source, expected, allSolutions, cmdlineOpt, check, before) {} FlatZincTest::FlatZincTest(TestTags tags, const std::string& name, @@ -127,7 +127,7 @@ namespace Test { namespace FlatZinc { const std::string& source, std::vector cmdlineOpt, std::string expectedMessage) - : FlatZincErrorTest(TestTag::normal, name, source, cmdlineOpt, + : FlatZincErrorTest(TestTags::standard(), name, source, cmdlineOpt, expectedMessage) {} FlatZincErrorTest::FlatZincErrorTest(TestTags tags, const std::string& name, diff --git a/test/flatzinc/blackbox.cpp b/test/flatzinc/blackbox.cpp index 8cad3592ee..548bff977b 100644 --- a/test/flatzinc/blackbox.cpp +++ b/test/flatzinc/blackbox.cpp @@ -258,7 +258,7 @@ namespace Test { namespace FlatZinc { public: NativeProtocol(void) : Base("FlatZinc::blackbox::native_protocol", - TestTags(TestTag::normal,TestTag::check)) {} + TestTags::check()) {} virtual bool run(void) { std::vector int_input{-2}; std::vector float_input{1.25}; @@ -374,7 +374,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { (void) new NativeProtocol; - (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::malformed_annotation", + (void) new FlatZincErrorTest(TestTags::check(),"blackbox::malformed_annotation", std::string(blackbox_decl) + "var 0..1: y;\n" "constraint gecode_blackbox([], [], [y], []) :: " @@ -386,7 +386,7 @@ namespace Test { namespace FlatZinc { const char* exec = std::getenv("GECODE_TEST_BLACKBOX_EXEC"); if (exec != nullptr) { const std::string executable(exec); - (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::constant_value", + (void) new FlatZincTest(TestTags::check(),"blackbox::constant_value", std::string(blackbox_decl) + "var 7..7: y :: output_var;\n" "constraint gecode_blackbox([], [], [y], []) :: " + @@ -394,7 +394,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", "y = 7;\n----------\n"); - (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::constant_value_unsat", + (void) new FlatZincTest(TestTags::check(),"blackbox::constant_value_unsat", std::string(blackbox_decl) + "var 8..8: y;\n" "constraint gecode_blackbox([], [], [y], []) :: " + @@ -402,7 +402,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", "=====UNSATISFIABLE=====\n"); - (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::reason_independent_bounds", + (void) new FlatZincTest(TestTags::check(),"blackbox::reason_independent_bounds", std::string(blackbox_bounds_decl) + "var 5..5: x :: output_var;\n" "constraint gecode_blackbox_bounds([x], [], [1,0,0]) :: " + @@ -410,7 +410,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", "x = 5;\n----------\n"); - (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::reason_independent_bounds_unsat", + (void) new FlatZincTest(TestTags::check(),"blackbox::reason_independent_bounds_unsat", std::string(blackbox_bounds_decl) + "var 6..6: x;\n" "constraint gecode_blackbox_bounds([x], [], [1,0,0]) :: " + @@ -418,7 +418,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", "=====UNSATISFIABLE=====\n"); - (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::reason_dependent_bounds", + (void) new FlatZincTest(TestTags::check(),"blackbox::reason_dependent_bounds", std::string(blackbox_bounds_decl) + "var 5..5: x :: output_var;\n" "constraint gecode_blackbox_bounds([x], [], [1,1,1,1,0]) :: " + @@ -426,7 +426,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", "x = 5;\n----------\n"); - (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::bounds_rescheduled_after_branch", + (void) new FlatZincTest(TestTags::check(),"blackbox::bounds_rescheduled_after_branch", std::string(blackbox_bounds_decl) + "var 0..1: x :: output_var;\n" "var 0..5: y :: output_var;\n" @@ -440,7 +440,7 @@ namespace Test { namespace FlatZinc { false, {"-a"}); #ifdef GECODE_HAS_FLOAT_VARS - (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::missing_bounds_reason_entry", + (void) new FlatZincErrorTest(TestTags::check(),"blackbox::missing_bounds_reason_entry", std::string(blackbox_bounds_decl) + "var 0..10: x;\n" "var 0.0..10.0: y;\n" @@ -449,7 +449,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", {}, "missing explained variable entry"); #endif - (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::duplicate_bounds_reason_entry", + (void) new FlatZincErrorTest(TestTags::check(),"blackbox::duplicate_bounds_reason_entry", std::string(blackbox_bounds_decl) + "var 0..10: x;\n" "var 0..10: y;\n" @@ -457,7 +457,7 @@ namespace Test { namespace FlatZinc { fixture_annotation("exec", executable, {"bounds4"}) + ";\n" "solve satisfy;\n", {}, "duplicate explained variable index"); - (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::invalid_bounds_reason_code", + (void) new FlatZincErrorTest(TestTags::check(),"blackbox::invalid_bounds_reason_code", std::string(blackbox_bounds_decl) + "var 0..10: x;\n" "constraint gecode_blackbox_bounds([x], [], [1,1,1,0,0]) :: " + @@ -465,7 +465,7 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", {}, "dependency bound code is out of range"); #ifdef GECODE_HAS_FLOAT_VARS - (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::invalid_float_output", + (void) new FlatZincErrorTest(TestTags::check(),"blackbox::invalid_float_output", std::string(blackbox_decl) + "var 0.0..10.0: y;\n" "constraint gecode_blackbox([], [], [], [y]) :: " + @@ -473,13 +473,13 @@ namespace Test { namespace FlatZinc { "solve satisfy;\n", {}, "Failed to read output float 0"); #endif - (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::nul_output", + (void) new FlatZincErrorTest(TestTags::check(),"blackbox::nul_output", std::string(blackbox_decl) + "constraint gecode_blackbox([], [], [], []) :: " + fixture_annotation("exec", executable, {"nul"}) + ";\n" "solve satisfy;\n", {}, "response contains NUL data"); - (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::malformed_exec_parallel", + (void) new FlatZincErrorTest(TestTags::check(),"blackbox::malformed_exec_parallel", std::string(blackbox_decl) + "var 0..1: x :: output_var;\n" "var 0..1: y :: output_var;\n" @@ -508,7 +508,7 @@ namespace Test { namespace FlatZinc { expected = "integer 0 is outside Gecode's integer range"; break; } - (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check), + (void) new FlatZincErrorTest(TestTags::check(), "blackbox::native_exec_fault_" + std::to_string(kind), std::string(blackbox_decl) + "var " + std::to_string(kind) + ".." + std::to_string(kind) + @@ -528,7 +528,7 @@ namespace Test { namespace FlatZinc { #if defined(GECODE_HAS_POSIX_BLACKBOX_EXEC) const std::string descendant_log = fixture_log("exec_descendant"); if (!descendant_log.empty()) { - (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::native_exec_descendant_cleanup", + (void) new FlatZincTest(TestTags::check(),"blackbox::native_exec_descendant_cleanup", std::string(blackbox_decl) + "var 1..1: y :: output_var;\n" "constraint gecode_blackbox([], [], [y], []) :: " + @@ -544,7 +544,7 @@ namespace Test { namespace FlatZinc { #endif } - (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::missing_exec_parallel", + (void) new FlatZincErrorTest(TestTags::check(),"blackbox::missing_exec_parallel", std::string(blackbox_decl) + "var 0..1: x :: output_var;\n" "var 0..1: y :: output_var;\n" @@ -554,7 +554,7 @@ namespace Test { namespace FlatZinc { "satisfy;\n", {"-p", "2"}, "starting blackbox process failed"); - (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::missing_exec_root_status", + (void) new FlatZincErrorTest(TestTags::check(),"blackbox::missing_exec_root_status", std::string(blackbox_decl) + "var 0..0: x :: output_var;\n" "var 0..1: y :: output_var;\n" @@ -569,7 +569,7 @@ namespace Test { namespace FlatZinc { const std::string library(dll); const std::string dll_model_log = fixture_log("dll_model"); if (!dll_model_log.empty()) { - (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"blackbox::native_dll_per_constraint", + (void) new FlatZincTest(TestTags::check(),"blackbox::native_dll_per_constraint", std::string(blackbox_decl) + "var 1..1: a :: output_var;\n" "var 1..1: b :: output_var;\n" @@ -596,7 +596,7 @@ namespace Test { namespace FlatZinc { #endif #ifdef GECODE_HAS_FLOAT_VARS - (void) new FlatZincErrorTest(TestTags(TestTag::normal,TestTag::check),"blackbox::native_dll_nonfinite", + (void) new FlatZincErrorTest(TestTags::check(),"blackbox::native_dll_nonfinite", std::string(blackbox_decl) + "var 0.0..1.0: y;\n" "constraint gecode_blackbox([], [], [], [y]) :: " + diff --git a/test/flatzinc/magicsq_3.cpp b/test/flatzinc/magicsq_3.cpp index 27f40f7737..c8d6e38d40 100755 --- a/test/flatzinc/magicsq_3.cpp +++ b/test/flatzinc/magicsq_3.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"magic_square::3", + (void) new FlatZincTest(TestTags::check(),"magic_square::3", "predicate all_different_int(array [int] of var int: x);\n\ predicate all_equal_int(array [int] of var int: x);\n\ predicate among(var int: n, array [int] of var int: x, set of int: v);\n\ diff --git a/test/flatzinc/magicsq_4.cpp b/test/flatzinc/magicsq_4.cpp index 807200b1e4..a8951c0377 100755 --- a/test/flatzinc/magicsq_4.cpp +++ b/test/flatzinc/magicsq_4.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"magic_square::4", + (void) new FlatZincTest(TestTags::check(),"magic_square::4", "predicate all_different_int(array [int] of var int: x);\n\ predicate all_equal_int(array [int] of var int: x);\n\ predicate among(var int: n, array [int] of var int: x, set of int: v);\n\ diff --git a/test/flatzinc/magicsq_5.cpp b/test/flatzinc/magicsq_5.cpp index 6ab2b86e1a..a08f84d319 100644 --- a/test/flatzinc/magicsq_5.cpp +++ b/test/flatzinc/magicsq_5.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTags(TestTag::normal,TestTag::check),"magic_square::5", + (void) new FlatZincTest(TestTags::check(),"magic_square::5", "predicate all_different_int(array [int] of var int: x);\n\ predicate all_equal_int(array [int] of var int: x);\n\ predicate among(var int: n, array [int] of var int: x, set of int: v);\n\ diff --git a/test/flatzinc/oss.cpp b/test/flatzinc/oss.cpp index 541e206b61..696f8e7d10 100644 --- a/test/flatzinc/oss.cpp +++ b/test/flatzinc/oss.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"oss", + (void) new FlatZincTest(TestTags::sweep(),"oss", "predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/packing.cpp b/test/flatzinc/packing.cpp index cce832a6e4..33cfe11d2b 100644 --- a/test/flatzinc/packing.cpp +++ b/test/flatzinc/packing.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"packing", + (void) new FlatZincTest(TestTags::sweep(),"packing", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/radiation.cpp b/test/flatzinc/radiation.cpp index c583d75875..5c06461e2b 100644 --- a/test/flatzinc/radiation.cpp +++ b/test/flatzinc/radiation.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"radiation", + (void) new FlatZincTest(TestTags::sweep(),"radiation", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/steiner_triples.cpp b/test/flatzinc/steiner_triples.cpp index 7beee4cd38..2205d82d8a 100644 --- a/test/flatzinc/steiner_triples.cpp +++ b/test/flatzinc/steiner_triples.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"steiner_triples", + (void) new FlatZincTest(TestTags::sweep(),"steiner_triples", "predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/template_design.cpp b/test/flatzinc/template_design.cpp index e3c33c16af..0e3b4ffdd0 100644 --- a/test/flatzinc/template_design.cpp +++ b/test/flatzinc/template_design.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"template_design", + (void) new FlatZincTest(TestTags::sweep(),"template_design", "predicate all_different_int(array [int] of var int: x);\n\ predicate all_equal_int(array [int] of var int: x);\n\ predicate among(var int: n, array [int] of var int: x, set of int: v);\n\ diff --git a/test/flatzinc/tenpenki_1.cpp b/test/flatzinc/tenpenki_1.cpp index 9e9521a4f3..f00ee717d1 100644 --- a/test/flatzinc/tenpenki_1.cpp +++ b/test/flatzinc/tenpenki_1.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"tenpenki::1", + (void) new FlatZincTest(TestTags::sweep(),"tenpenki::1", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/tenpenki_2.cpp b/test/flatzinc/tenpenki_2.cpp index 791a1b88ba..7386d8196d 100644 --- a/test/flatzinc/tenpenki_2.cpp +++ b/test/flatzinc/tenpenki_2.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"tenpenki::1", + (void) new FlatZincTest(TestTags::sweep(),"tenpenki::1", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/tenpenki_3.cpp b/test/flatzinc/tenpenki_3.cpp index bbceae472b..cf922308ad 100644 --- a/test/flatzinc/tenpenki_3.cpp +++ b/test/flatzinc/tenpenki_3.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"tenpenki::3", + (void) new FlatZincTest(TestTags::sweep(),"tenpenki::3", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/tenpenki_4.cpp b/test/flatzinc/tenpenki_4.cpp index ee9e2e6b47..7d1b31889b 100644 --- a/test/flatzinc/tenpenki_4.cpp +++ b/test/flatzinc/tenpenki_4.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"tenpenki::4", + (void) new FlatZincTest(TestTags::sweep(),"tenpenki::4", "predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/tenpenki_5.cpp b/test/flatzinc/tenpenki_5.cpp index bffbd629fe..f7a9224b6e 100644 --- a/test/flatzinc/tenpenki_5.cpp +++ b/test/flatzinc/tenpenki_5.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"tenpenki::5", + (void) new FlatZincTest(TestTags::sweep(),"tenpenki::5", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/tenpenki_6.cpp b/test/flatzinc/tenpenki_6.cpp index 9bb7904425..31fce97cdc 100644 --- a/test/flatzinc/tenpenki_6.cpp +++ b/test/flatzinc/tenpenki_6.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"tenpenki::6", + (void) new FlatZincTest(TestTags::sweep(),"tenpenki::6", std::string("predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/flatzinc/timetabling.cpp b/test/flatzinc/timetabling.cpp index f02ce689e8..857409e3a2 100644 --- a/test/flatzinc/timetabling.cpp +++ b/test/flatzinc/timetabling.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"timetabling", + (void) new FlatZincTest(TestTags::sweep(),"timetabling", std::string("predicate all_different_int(array [int] of var int: x);\n\ predicate all_equal_int(array [int] of var int: x);\n\ predicate among(var int: n, array [int] of var int: x, set of int: v);\n\ diff --git a/test/flatzinc/trucking.cpp b/test/flatzinc/trucking.cpp index fa9394cae4..35ce78fb5a 100644 --- a/test/flatzinc/trucking.cpp +++ b/test/flatzinc/trucking.cpp @@ -42,7 +42,7 @@ namespace Test { namespace FlatZinc { /// Perform creation and registration Create(void) { - (void) new FlatZincTest(TestTag::sweep,"trucking", + (void) new FlatZincTest(TestTags::sweep(),"trucking", "predicate bool_lin_ge(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_gt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ predicate bool_lin_lt(array [int] of int: a, array [int] of var bool: x, var int: c);\n\ diff --git a/test/float.hpp b/test/float.hpp index 4a05788233..bf9b716e60 100755 --- a/test/float.hpp +++ b/test/float.hpp @@ -183,7 +183,7 @@ namespace Test { namespace Float { Test::Test(const std::string& s, int a, const Gecode::FloatVal& d, Gecode::FloatNum st, AssignmentType at, bool r) - : Test(TestTag::normal,s,a,d,st,at,r) {} + : Test(TestTags::standard(),s,a,d,st,at,r) {} inline Test::Test(TestTags tags, const std::string& s, int a, @@ -200,7 +200,7 @@ namespace Test { namespace Float { Test::Test(const std::string& s, int a, Gecode::FloatNum min, Gecode::FloatNum max, Gecode::FloatNum st, AssignmentType at, bool r) - : Test(TestTag::normal,s,a,min,max,st,at,r) {} + : Test(TestTags::standard(),s,a,min,max,st,at,r) {} inline std::string diff --git a/test/float/arithmetic.cpp b/test/float/arithmetic.cpp index 644866993e..b1d79cb0f8 100755 --- a/test/float/arithmetic.cpp +++ b/test/float/arithmetic.cpp @@ -135,7 +135,7 @@ namespace Test { namespace Float { /// Create and register test PositiveNRootBounds(void) : Base("Float::Arithmetic::PositiveNRootBounds", - TestTags(TestTag::normal,TestTag::check)) {} + TestTags::check()) {} /// Run test under every supported IEEE-754 rounding mode virtual bool run(void) { const int oldMode = std::fegetround(); @@ -367,7 +367,7 @@ namespace Test { namespace Float { /// Create and register test PowConsistency(void) : Base("Float::Arithmetic::PowConsistency", - TestTags(TestTag::normal,TestTag::check)) {} + TestTags::check()) {} /// Run zero and fixpoint regressions virtual bool run(void) { bool result = true; @@ -490,7 +490,7 @@ namespace Test { namespace Float { /// Create and register test MultZeroEndpoint(void) : Base("Float::Arithmetic::MultZeroEndpoint", - TestTags(TestTag::normal,TestTag::check)) {} + TestTags::check()) {} /// Run sign, symmetry, signed-zero, and zero-product cases virtual bool run(void) { bool result = true; @@ -529,7 +529,7 @@ namespace Test { namespace Float { public: /// Create and register test MultXYZ(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Mult::XYZ::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Mult::XYZ::"+s,3,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[1], x[2]); @@ -576,7 +576,7 @@ namespace Test { namespace Float { public: /// Create and register test MultXXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Mult::XXY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Mult::XXY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[0], x[1]); @@ -592,7 +592,7 @@ namespace Test { namespace Float { public: /// Create and register test MultXXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Mult::XXY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Mult::XXY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[0], x[1]); @@ -618,7 +618,7 @@ namespace Test { namespace Float { public: /// Create and register test MultXYX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Mult::XYX::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Mult::XYX::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[1], x[0]); @@ -634,7 +634,7 @@ namespace Test { namespace Float { public: /// Create and register test MultXYY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Mult::XYY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Mult::XYY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[1], x[1]); @@ -650,7 +650,7 @@ namespace Test { namespace Float { public: /// Create and register test MultXXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Mult::XXX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Mult::XXX::"+s,1,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[0], x[0]); @@ -687,7 +687,7 @@ namespace Test { namespace Float { public: /// Create and register test DivSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Div::Sol::"+s,3,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Div::Sol::"+s,3,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] / x[1], x[2]); @@ -713,7 +713,7 @@ namespace Test { namespace Float { public: /// Create and register test SqrXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Sqr::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Sqr::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[0], x[1]); @@ -732,7 +732,7 @@ namespace Test { namespace Float { public: /// Create and register test SqrXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Sqr::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Sqr::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(x[0] * x[0], x[1]); @@ -776,7 +776,7 @@ namespace Test { namespace Float { public: /// Create and register test SqrtXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Sqrt::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Sqrt::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { switch (cmp(x[0], Gecode::FRT_GQ, 0.0)) { @@ -800,7 +800,7 @@ namespace Test { namespace Float { public: /// Create and register test SqrtXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Sqrt::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Sqrt::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { switch (cmp(x[0], Gecode::FRT_GQ, 0.0)) { @@ -855,7 +855,7 @@ namespace Test { namespace Float { public: /// Create and register test PowXY(const std::string& s, const Gecode::FloatVal& d, unsigned int _n, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Pow::N::"+str(_n)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), n(_n) {} + : Test(TestTags::sweep(),"Arithmetic::Pow::N::"+str(_n)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), n(_n) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(pow(x[0],n), x[1]); @@ -905,7 +905,7 @@ namespace Test { namespace Float { public: /// Create and register test PowXX(const std::string& s, const Gecode::FloatVal& d, unsigned int _n, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Pow::N::"+str(_n)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), n(_n) {} + : Test(TestTags::sweep(),"Arithmetic::Pow::N::"+str(_n)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), n(_n) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(pow(x[0],n), x[0]); @@ -922,7 +922,7 @@ namespace Test { namespace Float { public: /// Create and register test NRootXY(const std::string& s, const Gecode::FloatVal& d, unsigned int _n, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::NRoot::N::"+str(_n)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), n(_n) {} + : Test(TestTags::sweep(),"Arithmetic::NRoot::N::"+str(_n)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), n(_n) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((n == 0) || (x[0].min() < 0.0)) @@ -978,7 +978,7 @@ namespace Test { namespace Float { public: /// Create and register test NRootXX(const std::string& s, const Gecode::FloatVal& d, unsigned int _n, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::NRoot::N::"+str(_n)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), n(_n) {} + : Test(TestTags::sweep(),"Arithmetic::NRoot::N::"+str(_n)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), n(_n) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((n == 0) || (x[0].min() < 0)) @@ -996,7 +996,7 @@ namespace Test { namespace Float { public: /// Create and register test AbsXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Abs::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Abs::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(abs(x[0]), x[1]); @@ -1054,7 +1054,7 @@ namespace Test { namespace Float { public: /// Create and register test MinXXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Min::Bin::XXY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Min::Bin::XXY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(x[0],x[0]), x[1]); @@ -1070,7 +1070,7 @@ namespace Test { namespace Float { public: /// Create and register test MinXYX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Min::Bin::XYX::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Min::Bin::XYX::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(x[0],x[1]), x[0]); @@ -1086,7 +1086,7 @@ namespace Test { namespace Float { public: /// Create and register test MinXYY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Min::Bin::XYY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Min::Bin::XYY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(x[0],x[1]), x[1]); @@ -1141,7 +1141,7 @@ namespace Test { namespace Float { public: /// Create and register test MaxXXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Max::Bin::XXY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Max::Bin::XXY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(x[0],x[0]), x[1]); @@ -1157,7 +1157,7 @@ namespace Test { namespace Float { public: /// Create and register test MaxXYX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Max::Bin::XYX::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Max::Bin::XYX::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(x[0],x[1]), x[0]); @@ -1173,7 +1173,7 @@ namespace Test { namespace Float { public: /// Create and register test MaxXYY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Arithmetic::Max::Bin::XYY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Max::Bin::XYY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(x[0],x[1]), x[1]); @@ -1207,7 +1207,7 @@ namespace Test { namespace Float { public: /// Create and register test MinNary(void) - : Test(TestTag::sweep,"Arithmetic::Min::Nary",4,-4,4,0.5,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Min::Nary",4,-4,4,0.5,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(min(x[0],x[1]),x[2]), x[3]); @@ -1228,7 +1228,7 @@ namespace Test { namespace Float { public: /// Create and register test MinNaryShared(void) - : Test(TestTag::sweep,"Arithmetic::Min::Nary::Shared",3,-4,4,0.5,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Min::Nary::Shared",3,-4,4,0.5,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(min(min(x[0],x[1]),x[2]), x[1]); @@ -1246,7 +1246,7 @@ namespace Test { namespace Float { public: /// Create and register test MaxNary(void) - : Test(TestTag::sweep,"Arithmetic::Max::Nary",4,-4,4,0.5,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Max::Nary",4,-4,4,0.5,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(max(x[0],x[1]),x[2]), x[3]); @@ -1267,7 +1267,7 @@ namespace Test { namespace Float { public: /// Create and register test MaxNaryShared(void) - : Test(TestTag::sweep,"Arithmetic::Max::Nary::Shared",3,-4,4,0.5,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Arithmetic::Max::Nary::Shared",3,-4,4,0.5,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(max(max(x[0],x[1]),x[2]), x[1]); @@ -1309,14 +1309,14 @@ namespace Test { namespace Float { MultXYZ mult_xyz_b("B",b,step); MultXYZ mult_xyz_c("C",c,step); - MultXYZSol mult_xyz_sol_a(TestTag::sweep,"A",a,step); - MultXYZSol mult_xyz_sol_b(TestTag::sweep,"B",b,step); + MultXYZSol mult_xyz_sol_a(TestTags::sweep(),"A",a,step); + MultXYZSol mult_xyz_sol_b(TestTags::sweep(),"B",b,step); MultXYZSol mult_xyz_sol_c( - TestTags(TestTag::normal,TestTag::check),"C",c,step); + TestTags::check(),"C",c,step); - Div div_a(TestTag::normal,"A",a,step); - Div div_b(TestTag::sweep,"B",b,step); - Div div_c(TestTag::sweep,"C",c,step); + Div div_a(TestTags::standard(),"A",a,step); + Div div_b(TestTags::sweep(),"B",b,step); + Div div_c(TestTags::sweep(),"C",c,step); DivSol div_sol_a("A",a,step); DivSol div_sol_b("B",b,step); @@ -1330,9 +1330,9 @@ namespace Test { namespace Float { SqrXYSol sqr_xy_sol_b("B",b,step); SqrXYSol sqr_xy_sol_c("C",c,step); - SqrXX sqr_xx_a(TestTag::normal,"A",a,step); - SqrXX sqr_xx_b(TestTag::sweep,"B",b,step); - SqrXX sqr_xx_c(TestTag::sweep,"C",c,step); + SqrXX sqr_xx_a(TestTags::standard(),"A",a,step); + SqrXX sqr_xx_b(TestTags::sweep(),"B",b,step); + SqrXX sqr_xx_c(TestTags::sweep(),"C",c,step); SqrtXY sqrt_xy_a("A",a,step); SqrtXY sqrt_xy_b("B",b,step); @@ -1342,18 +1342,18 @@ namespace Test { namespace Float { SqrtXYSol sqrt_xy_sol_b("B",b,step); SqrtXYSol sqrt_xy_sol_c("C",c,step); - SqrtXX sqrt_xx_a(TestTag::normal,"A",a,step); - SqrtXX sqrt_xx_b(TestTag::sweep,"B",b,step); - SqrtXX sqrt_xx_c(TestTag::sweep,"C",c,step); + SqrtXX sqrt_xx_a(TestTags::standard(),"A",a,step); + SqrtXX sqrt_xx_b(TestTags::sweep(),"B",b,step); + SqrtXX sqrt_xx_c(TestTags::sweep(),"C",c,step); PowXY pow_xy_a_1("A",a,2,step); PowXY pow_xy_b_1("B",b,2,step); PowXY pow_xy_c_1("C",c,2,step); - PowXYSol pow_xy_sol_a_1(TestTag::sweep,"A",a,2,step); - PowXYSol pow_xy_sol_b_1(TestTag::sweep,"B",b,2,step); + PowXYSol pow_xy_sol_a_1(TestTags::sweep(),"A",a,2,step); + PowXYSol pow_xy_sol_b_1(TestTags::sweep(),"B",b,2,step); PowXYSol pow_xy_sol_c_1( - TestTags(TestTag::normal,TestTag::check),"C",c,2,step); + TestTags::check(),"C",c,2,step); PowXX pow_xx_a_1("A",a,2,step); PowXX pow_xx_b_1("B",b,2,step); @@ -1363,9 +1363,9 @@ namespace Test { namespace Float { PowXY pow_xy_b_2("B",b,3,step); PowXY pow_xy_c_2("C",c,3,step); - PowXYSol pow_xy_sol_a_2(TestTag::sweep,"A",a,3,step); - PowXYSol pow_xy_sol_b_2(TestTag::sweep,"B",b,3,step); - PowXYSol pow_xy_sol_c_2(TestTag::sweep,"C",c,3,step); + PowXYSol pow_xy_sol_a_2(TestTags::sweep(),"A",a,3,step); + PowXYSol pow_xy_sol_b_2(TestTags::sweep(),"B",b,3,step); + PowXYSol pow_xy_sol_c_2(TestTags::sweep(),"C",c,3,step); PowXX pow_xx_a_2("A",a,3,step); PowXX pow_xx_b_2("B",b,3,step); @@ -1375,9 +1375,9 @@ namespace Test { namespace Float { PowXY pow_xy_b_3("B",b,0,step); PowXY pow_xy_c_3("C",c,0,step); - PowXYSol pow_xy_sol_a_3(TestTag::sweep,"A",a,0,step); - PowXYSol pow_xy_sol_b_3(TestTag::sweep,"B",b,0,step); - PowXYSol pow_xy_sol_c_3(TestTag::sweep,"C",c,0,step); + PowXYSol pow_xy_sol_a_3(TestTags::sweep(),"A",a,0,step); + PowXYSol pow_xy_sol_b_3(TestTags::sweep(),"B",b,0,step); + PowXYSol pow_xy_sol_c_3(TestTags::sweep(),"C",c,0,step); PowXX pow_xx_a_3("A",a,0,step); PowXX pow_xx_b_3("B",b,0,step); @@ -1387,10 +1387,10 @@ namespace Test { namespace Float { NRootXY nroot_xy_b_1("B",b,2,step); NRootXY nroot_xy_c_1("C",c,2,step); - NRootXYSol nroot_xy_sol_a_1(TestTag::sweep,"A",a,2,step); - NRootXYSol nroot_xy_sol_b_1(TestTag::sweep,"B",b,2,step); + NRootXYSol nroot_xy_sol_a_1(TestTags::sweep(),"A",a,2,step); + NRootXYSol nroot_xy_sol_b_1(TestTags::sweep(),"B",b,2,step); NRootXYSol nroot_xy_sol_c_1( - TestTags(TestTag::normal,TestTag::check),"C",c,2,step); + TestTags::check(),"C",c,2,step); NRootXX nroot_xx_a_1("A",a,2,step); NRootXX nroot_xx_b_1("B",b,2,step); @@ -1400,9 +1400,9 @@ namespace Test { namespace Float { NRootXY nroot_xy_b_2("B",b,3,step); NRootXY nroot_xy_c_2("C",c,3,step); - NRootXYSol nroot_xy_sol_a_2(TestTag::sweep,"A",a,3,step); - NRootXYSol nroot_xy_sol_b_2(TestTag::sweep,"B",b,3,step); - NRootXYSol nroot_xy_sol_c_2(TestTag::sweep,"C",c,3,step); + NRootXYSol nroot_xy_sol_a_2(TestTags::sweep(),"A",a,3,step); + NRootXYSol nroot_xy_sol_b_2(TestTags::sweep(),"B",b,3,step); + NRootXYSol nroot_xy_sol_c_2(TestTags::sweep(),"C",c,3,step); NRootXX nroot_xx_a_2("A",a,3,step); NRootXX nroot_xx_b_2("B",b,3,step); @@ -1412,9 +1412,9 @@ namespace Test { namespace Float { NRootXY nroot_xy_b_3("B",b,0,step); NRootXY nroot_xy_c_3("C",c,0,step); - NRootXYSol nroot_xy_sol_a_3(TestTag::sweep,"A",a,0,step); - NRootXYSol nroot_xy_sol_b_3(TestTag::sweep,"B",b,0,step); - NRootXYSol nroot_xy_sol_c_3(TestTag::sweep,"C",c,0,step); + NRootXYSol nroot_xy_sol_a_3(TestTags::sweep(),"A",a,0,step); + NRootXYSol nroot_xy_sol_b_3(TestTags::sweep(),"B",b,0,step); + NRootXYSol nroot_xy_sol_c_3(TestTags::sweep(),"C",c,0,step); NRootXX nroot_xx_a_3("A",a,0,step); NRootXX nroot_xx_b_3("B",b,0,step); @@ -1424,16 +1424,16 @@ namespace Test { namespace Float { AbsXY abs_xy_b("B",b,step); AbsXY abs_xy_c("C",c,step); - AbsXX abs_xx_a(TestTag::normal,"A",a,step); - AbsXX abs_xx_b(TestTag::sweep,"B",b,step); - AbsXX abs_xx_c(TestTag::sweep,"C",c,step); + AbsXX abs_xx_a(TestTags::standard(),"A",a,step); + AbsXX abs_xx_b(TestTags::sweep(),"B",b,step); + AbsXX abs_xx_c(TestTags::sweep(),"C",c,step); MinXYZ min_xyz_normal( - TestTag::normal,"Normal",Gecode::FloatVal(-1,1),1.0); + TestTags::standard(),"Normal",Gecode::FloatVal(-1,1),1.0); - MinXYZ min_xyz_a(TestTag::sweep,"A",a,step); - MinXYZ min_xyz_b(TestTag::sweep,"B",b,step); - MinXYZ min_xyz_c(TestTag::sweep,"C",c,step); + MinXYZ min_xyz_a(TestTags::sweep(),"A",a,step); + MinXYZ min_xyz_b(TestTags::sweep(),"B",b,step); + MinXYZ min_xyz_c(TestTags::sweep(),"C",c,step); MinXXY min_xxy_a("A",a,step); MinXXY min_xxy_b("B",b,step); @@ -1447,16 +1447,16 @@ namespace Test { namespace Float { MinXYY min_xyy_b("B",b,step); MinXYY min_xyy_c("C",c,step); - MinXXX min_xxx_a(TestTag::normal,"A",a,step); - MinXXX min_xxx_b(TestTag::sweep,"B",b,step); - MinXXX min_xxx_c(TestTag::sweep,"C",c,step); + MinXXX min_xxx_a(TestTags::standard(),"A",a,step); + MinXXX min_xxx_b(TestTags::sweep(),"B",b,step); + MinXXX min_xxx_c(TestTags::sweep(),"C",c,step); MaxXYZ max_xyz_normal( - TestTag::normal,"Normal",Gecode::FloatVal(-1,1),1.0); + TestTags::standard(),"Normal",Gecode::FloatVal(-1,1),1.0); - MaxXYZ max_xyz_a(TestTag::sweep,"A",a,step); - MaxXYZ max_xyz_b(TestTag::sweep,"B",b,step); - MaxXYZ max_xyz_c(TestTag::sweep,"C",c,step); + MaxXYZ max_xyz_a(TestTags::sweep(),"A",a,step); + MaxXYZ max_xyz_b(TestTags::sweep(),"B",b,step); + MaxXYZ max_xyz_c(TestTags::sweep(),"C",c,step); MaxXXY max_xxy_a("A",a,step); MaxXXY max_xxy_b("B",b,step); @@ -1470,9 +1470,9 @@ namespace Test { namespace Float { MaxXYY max_xyy_b("B",b,step); MaxXYY max_xyy_c("C",c,step); - MaxXXX max_xxx_a(TestTag::normal,"A",a,step); - MaxXXX max_xxx_b(TestTag::sweep,"B",b,step); - MaxXXX max_xxx_c(TestTag::sweep,"C",c,step); + MaxXXX max_xxx_a(TestTags::standard(),"A",a,step); + MaxXXX max_xxx_b(TestTags::sweep(),"B",b,step); + MaxXXX max_xxx_c(TestTags::sweep(),"C",c,step); MinNary min_nary; MinNaryShared min_s_nary; diff --git a/test/float/linear.cpp b/test/float/linear.cpp index 1796f1e6f6..d536f39d57 100644 --- a/test/float/linear.cpp +++ b/test/float/linear.cpp @@ -206,12 +206,12 @@ namespace Test { namespace Float { for (FloatRelTypes frts; frts(); ++frts) { TestTags tags = frts.frt() == Gecode::FRT_EQ - ? TestTag::normal : TestTag::sweep; + ? TestTags::standard() : TestTags::sweep(); (void) new FloatFloat(tags,"11",f1,a1,frts.frt(),0.0,step); (void) new FloatVar(tags,"11",f1,a1,frts.frt(),step); - (void) new FloatFloat(TestTag::sweep,"21",f2,a1,frts.frt(),0.0,step); - (void) new FloatVar(TestTag::sweep,"21",f2,a1,frts.frt(),step); - (void) new FloatFloat(TestTag::sweep,"31",f3,a1,frts.frt(),1.0,step); + (void) new FloatFloat(TestTags::sweep(),"21",f2,a1,frts.frt(),0.0,step); + (void) new FloatVar(TestTags::sweep(),"21",f2,a1,frts.frt(),step); + (void) new FloatFloat(TestTags::sweep(),"31",f3,a1,frts.frt(),1.0,step); } const FloatVal av2[4] = {1.0,1.0,1.0,1.0}; @@ -225,24 +225,24 @@ namespace Test { namespace Float { FloatValArgs a4(i, av4); FloatValArgs a5(i, av5); for (FloatRelTypes frts; frts(); ++frts) { - (void) new FloatFloat(TestTag::sweep,"12",f1,a2,frts.frt(),0.0,step); - (void) new FloatFloat(TestTag::sweep,"13",f1,a3,frts.frt(),0.0,step); - (void) new FloatFloat(TestTag::sweep,"14",f1,a4,frts.frt(),0.0,step); - (void) new FloatFloat(TestTag::sweep,"15",f1,a5,frts.frt(),0.0,step); - (void) new FloatFloat(TestTag::sweep,"22",f2,a2,frts.frt(),0.0,step); - (void) new FloatFloat(TestTag::sweep,"23",f2,a3,frts.frt(),0.0,step); - (void) new FloatFloat(TestTag::sweep,"24",f2,a4,frts.frt(),0.0,step); - (void) new FloatFloat(TestTag::sweep,"25",f2,a5,frts.frt(),0.0,step); - (void) new FloatFloat(TestTag::sweep,"32",f3,a2,frts.frt(),1.0,step); + (void) new FloatFloat(TestTags::sweep(),"12",f1,a2,frts.frt(),0.0,step); + (void) new FloatFloat(TestTags::sweep(),"13",f1,a3,frts.frt(),0.0,step); + (void) new FloatFloat(TestTags::sweep(),"14",f1,a4,frts.frt(),0.0,step); + (void) new FloatFloat(TestTags::sweep(),"15",f1,a5,frts.frt(),0.0,step); + (void) new FloatFloat(TestTags::sweep(),"22",f2,a2,frts.frt(),0.0,step); + (void) new FloatFloat(TestTags::sweep(),"23",f2,a3,frts.frt(),0.0,step); + (void) new FloatFloat(TestTags::sweep(),"24",f2,a4,frts.frt(),0.0,step); + (void) new FloatFloat(TestTags::sweep(),"25",f2,a5,frts.frt(),0.0,step); + (void) new FloatFloat(TestTags::sweep(),"32",f3,a2,frts.frt(),1.0,step); if (i < 4) { - (void) new FloatVar(TestTag::sweep,"12",f1,a2,frts.frt(),step); - (void) new FloatVar(TestTag::sweep,"13",f1,a3,frts.frt(),step); - (void) new FloatVar(TestTag::sweep,"14",f1,a4,frts.frt(),step); - (void) new FloatVar(TestTag::sweep,"15",f1,a5,frts.frt(),step); - (void) new FloatVar(TestTag::sweep,"22",f2,a2,frts.frt(),step); - (void) new FloatVar(TestTag::sweep,"23",f2,a3,frts.frt(),step); - (void) new FloatVar(TestTag::sweep,"24",f2,a4,frts.frt(),step); - (void) new FloatVar(TestTag::sweep,"25",f2,a5,frts.frt(),step); + (void) new FloatVar(TestTags::sweep(),"12",f1,a2,frts.frt(),step); + (void) new FloatVar(TestTags::sweep(),"13",f1,a3,frts.frt(),step); + (void) new FloatVar(TestTags::sweep(),"14",f1,a4,frts.frt(),step); + (void) new FloatVar(TestTags::sweep(),"15",f1,a5,frts.frt(),step); + (void) new FloatVar(TestTags::sweep(),"22",f2,a2,frts.frt(),step); + (void) new FloatVar(TestTags::sweep(),"23",f2,a3,frts.frt(),step); + (void) new FloatVar(TestTags::sweep(),"24",f2,a4,frts.frt(),step); + (void) new FloatVar(TestTags::sweep(),"25",f2,a5,frts.frt(),step); } } } diff --git a/test/float/mm-lin.cpp b/test/float/mm-lin.cpp index 29857890dc..172f6d8e01 100644 --- a/test/float/mm-lin.cpp +++ b/test/float/mm-lin.cpp @@ -1874,7 +1874,7 @@ namespace Test { namespace Float { } else if (i < 100) { s = "0" + s; } - (void) new LinExpr(i == 0 ? TestTag::normal : TestTag::sweep, + (void) new LinExpr(i == 0 ? TestTags::standard() : TestTags::sweep(), li[i],s); } FloatRelTypes frts; diff --git a/test/float/transcendental.cpp b/test/float/transcendental.cpp index 4e589d1399..0445017139 100644 --- a/test/float/transcendental.cpp +++ b/test/float/transcendental.cpp @@ -51,7 +51,7 @@ namespace Test { namespace Float { public: /// Create and register test ExpXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Transcendental::Exp::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Transcendental::Exp::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(exp(x[0]), x[1]); @@ -70,7 +70,7 @@ namespace Test { namespace Float { public: /// Create and register test ExpXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Transcendental::Exp::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Transcendental::Exp::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(exp(x[0]), x[1]); @@ -114,7 +114,7 @@ namespace Test { namespace Float { public: /// Create and register test LogXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Transcendental::Log::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Transcendental::Log::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if (x[0].max() < 0.0) @@ -135,7 +135,7 @@ namespace Test { namespace Float { public: /// Create and register test LogXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Transcendental::Log::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Transcendental::Log::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if (x[0].max() < 0.0) @@ -185,7 +185,7 @@ namespace Test { namespace Float { public: /// Create and register test LogNXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum _base, Gecode::FloatNum st) - : Test(TestTag::sweep,"Transcendental::Log::N::"+str(_base)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), base(_base) {} + : Test(TestTags::sweep(),"Transcendental::Log::N::"+str(_base)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), base(_base) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].max() <= 0.0) || (base <= 0.0)) @@ -204,7 +204,7 @@ namespace Test { namespace Float { public: /// Create and register test LogNXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum _base, Gecode::FloatNum st) - : Test(TestTag::sweep,"Transcendental::Log::N::"+str(_base)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), base(_base) {} + : Test(TestTags::sweep(),"Transcendental::Log::N::"+str(_base)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), base(_base) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].max() <= 0.0) || (base <= 0.0)) @@ -235,7 +235,7 @@ namespace Test { namespace Float { public: /// Create and register test LogNXX(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum _base, Gecode::FloatNum st) - : Test(TestTag::sweep,"Transcendental::Log::N::"+str(_base)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), base(_base) {} + : Test(TestTags::sweep(),"Transcendental::Log::N::"+str(_base)+"::XX::"+s,1,d,st,CPLT_ASSIGNMENT,false), base(_base) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].max() <= 0.0) || (base <= 0.0)) @@ -254,7 +254,7 @@ namespace Test { namespace Float { public: /// Create and register test PowXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum _base, Gecode::FloatNum st) - : Test(TestTag::sweep,"Transcendental::Pow::N::"+str(_base)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), base(_base) {} + : Test(TestTags::sweep(),"Transcendental::Pow::N::"+str(_base)+"::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false), base(_base) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if (base <= 0.0) @@ -273,7 +273,7 @@ namespace Test { namespace Float { public: /// Create and register test PowXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum _base, Gecode::FloatNum st) - : Test(TestTag::sweep,"Transcendental::Pow::N::"+str(_base)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), base(_base) {} + : Test(TestTags::sweep(),"Transcendental::Pow::N::"+str(_base)+"::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false), base(_base) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if (base <= 0.0) @@ -334,9 +334,9 @@ namespace Test { namespace Float { ExpXYSol exp_xy_sol_b("B",b,step); ExpXYSol exp_xy_sol_c("C",c,step); - ExpXX exp_xx_a(TestTag::normal,"A",a,step); - ExpXX exp_xx_b(TestTag::sweep,"B",b,step); - ExpXX exp_xx_c(TestTag::sweep,"C",c,step); + ExpXX exp_xx_a(TestTags::standard(),"A",a,step); + ExpXX exp_xx_b(TestTags::sweep(),"B",b,step); + ExpXX exp_xx_c(TestTags::sweep(),"C",c,step); LogXY log_xy_a("A",a,step); LogXY log_xy_b("B",b,step); @@ -346,9 +346,9 @@ namespace Test { namespace Float { LogXYSol log_xy_sol_b("B",b,step); LogXYSol log_xy_sol_c("C",c,step); - LogXX log_xx_a(TestTag::normal,"A",a,step); - LogXX log_xx_b(TestTag::sweep,"B",b,step); - LogXX log_xx_c(TestTag::sweep,"C",c,step); + LogXX log_xx_a(TestTags::standard(),"A",a,step); + LogXX log_xx_b(TestTags::sweep(),"B",b,step); + LogXX log_xx_c(TestTags::sweep(),"C",c,step); LogNXY logn_xy_a_1("A",a,-1.5,step); LogNXY logn_xy_b_1("B",b,-1.5,step); @@ -394,9 +394,9 @@ namespace Test { namespace Float { PowXYSol pow_xy_sol_b_1("B",b,-1.5,step); PowXYSol pow_xy_sol_c_1("C",c,-1.5,step); - PowXX pow_xx_a_1(TestTag::sweep,"A",a,-1.5,step); - PowXX pow_xx_b_1(TestTag::sweep,"B",b,-1.5,step); - PowXX pow_xx_c_1(TestTag::sweep,"C",c,-1.5,step); + PowXX pow_xx_a_1(TestTags::sweep(),"A",a,-1.5,step); + PowXX pow_xx_b_1(TestTags::sweep(),"B",b,-1.5,step); + PowXX pow_xx_c_1(TestTags::sweep(),"C",c,-1.5,step); PowXY pow_xy_a_2("A",a,1.5,step); PowXY pow_xy_b_2("B",b,1.5,step); @@ -406,9 +406,9 @@ namespace Test { namespace Float { PowXYSol pow_xy_sol_b_2("B",b,1.5,step); PowXYSol pow_xy_sol_c_2("C",c,1.5,step); - PowXX pow_xx_a_2(TestTag::normal,"A",a,1.5,step); - PowXX pow_xx_b_2(TestTag::sweep,"B",b,1.5,step); - PowXX pow_xx_c_2(TestTag::sweep,"C",c,1.5,step); + PowXX pow_xx_a_2(TestTags::standard(),"A",a,1.5,step); + PowXX pow_xx_b_2(TestTags::sweep(),"B",b,1.5,step); + PowXX pow_xx_c_2(TestTags::sweep(),"C",c,1.5,step); PowXY pow_xy_a_3("A",a,0,step); PowXY pow_xy_b_3("B",b,0,step); @@ -418,9 +418,9 @@ namespace Test { namespace Float { PowXYSol pow_xy_sol_b_3("B",b,0,step); PowXYSol pow_xy_sol_c_3("C",c,0,step); - PowXX pow_xx_a_3(TestTag::sweep,"A",a,0,step); - PowXX pow_xx_b_3(TestTag::sweep,"B",b,0,step); - PowXX pow_xx_c_3(TestTag::sweep,"C",c,0,step); + PowXX pow_xx_a_3(TestTags::sweep(),"A",a,0,step); + PowXX pow_xx_b_3(TestTags::sweep(),"B",b,0,step); + PowXX pow_xx_c_3(TestTags::sweep(),"C",c,0,step); //@} diff --git a/test/float/trigonometric.cpp b/test/float/trigonometric.cpp index 35f02f263e..3c5e1ccde7 100644 --- a/test/float/trigonometric.cpp +++ b/test/float/trigonometric.cpp @@ -51,7 +51,7 @@ namespace Test { namespace Float { public: /// Create and register test SinXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Trigonometric::Sin::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Trigonometric::Sin::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(sin(x[0]), x[1]); @@ -70,7 +70,7 @@ namespace Test { namespace Float { public: /// Create and register test SinXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Trigonometric::Sin::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Trigonometric::Sin::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(sin(x[0]), x[1]); @@ -114,7 +114,7 @@ namespace Test { namespace Float { public: /// Create and register test CosXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Trigonometric::Cos::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Trigonometric::Cos::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(cos(x[0]), x[1]); @@ -133,7 +133,7 @@ namespace Test { namespace Float { public: /// Create and register test CosXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Trigonometric::Cos::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Trigonometric::Cos::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(cos(x[0]), x[1]); @@ -177,7 +177,7 @@ namespace Test { namespace Float { public: /// Create and register test TanXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Trigonometric::Tan::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Trigonometric::Tan::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(tan(x[0]), x[1]); @@ -196,7 +196,7 @@ namespace Test { namespace Float { public: /// Create and register test TanXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Trigonometric::Tan::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Trigonometric::Tan::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(tan(x[0]), x[1]); @@ -240,7 +240,7 @@ namespace Test { namespace Float { public: /// Create and register test ASinXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Trigonometric::ASin::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Trigonometric::ASin::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].min() > 1.0) || (x[0].max() < -1.0)) @@ -261,7 +261,7 @@ namespace Test { namespace Float { public: /// Create and register test ASinXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Trigonometric::ASin::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Trigonometric::ASin::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].min() > 1.0) || (x[0].max() < -1.0)) @@ -311,7 +311,7 @@ namespace Test { namespace Float { public: /// Create and register test ACosXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Trigonometric::ACos::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Trigonometric::ACos::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].min() > 1.0) || (x[0].max() < -1.0)) @@ -332,7 +332,7 @@ namespace Test { namespace Float { public: /// Create and register test ACosXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Trigonometric::ACos::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Trigonometric::ACos::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { if ((x[0].min() > 1.0) || (x[0].max() < -1.0)) @@ -382,7 +382,7 @@ namespace Test { namespace Float { public: /// Create and register test ATanXY(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Trigonometric::ATan::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Trigonometric::ATan::XY::"+s,2,d,st,CPLT_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(atan(x[0]), x[1]); @@ -401,7 +401,7 @@ namespace Test { namespace Float { public: /// Create and register test ATanXYSol(const std::string& s, const Gecode::FloatVal& d, Gecode::FloatNum st) - : Test(TestTag::sweep,"Trigonometric::ATan::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} + : Test(TestTags::sweep(),"Trigonometric::ATan::XY::Sol::"+s,2,d,st,EXTEND_ASSIGNMENT,false) {} /// %Test whether \a x is solution virtual MaybeType solution(const Assignment& x) const { return eq(atan(x[0]), x[1]); @@ -454,9 +454,9 @@ namespace Test { namespace Float { SinXYSol sin_xy_sol_b("B",b,step); SinXYSol sin_xy_sol_c("C",c,step); - SinXX sin_xx_a(TestTag::normal,"A",a,step); - SinXX sin_xx_b(TestTag::sweep,"B",b,step); - SinXX sin_xx_c(TestTag::sweep,"C",c,step); + SinXX sin_xx_a(TestTags::standard(),"A",a,step); + SinXX sin_xx_b(TestTags::sweep(),"B",b,step); + SinXX sin_xx_c(TestTags::sweep(),"C",c,step); CosXY cos_xy_a("A",a,step); CosXY cos_xy_b("B",b,step); @@ -466,9 +466,9 @@ namespace Test { namespace Float { CosXYSol cos_xy_sol_b("B",b,step); CosXYSol cos_xy_sol_c("C",c,step); - CosXX cos_xx_a(TestTag::normal,"A",a,step); - CosXX cos_xx_b(TestTag::sweep,"B",b,step); - CosXX cos_xx_c(TestTag::sweep,"C",c,step); + CosXX cos_xx_a(TestTags::standard(),"A",a,step); + CosXX cos_xx_b(TestTags::sweep(),"B",b,step); + CosXX cos_xx_c(TestTags::sweep(),"C",c,step); TanXY tan_xy_a("A",a,step); TanXY tan_xy_b("B",b,step); @@ -478,9 +478,9 @@ namespace Test { namespace Float { TanXYSol tan_xy_sol_b("B",b,step); TanXYSol tan_xy_sol_c("C",c,step); - TanXX tan_xx_a(TestTag::normal,"A",a,step); - TanXX tan_xx_b(TestTag::sweep,"B",b,step); - TanXX tan_xx_c(TestTag::sweep,"C",c,step); + TanXX tan_xx_a(TestTags::standard(),"A",a,step); + TanXX tan_xx_b(TestTags::sweep(),"B",b,step); + TanXX tan_xx_c(TestTags::sweep(),"C",c,step); ASinXY asin_xy_a("A",a,step); ASinXY asin_xy_b("B",b,step); @@ -490,9 +490,9 @@ namespace Test { namespace Float { ASinXYSol asin_xy_sol_b("B",b,step); ASinXYSol asin_xy_sol_c("C",c,step); - ASinXX asin_xx_a(TestTag::normal,"A",a,step); - ASinXX asin_xx_b(TestTag::sweep,"B",b,step); - ASinXX asin_xx_c(TestTag::sweep,"C",c,step); + ASinXX asin_xx_a(TestTags::standard(),"A",a,step); + ASinXX asin_xx_b(TestTags::sweep(),"B",b,step); + ASinXX asin_xx_c(TestTags::sweep(),"C",c,step); ACosXY acos_xy_a("A",a,step); ACosXY acos_xy_b("B",b,step); @@ -502,9 +502,9 @@ namespace Test { namespace Float { ACosXYSol acos_xy_sol_b("B",b,step); ACosXYSol acos_xy_sol_c("C",c,step); - ACosXX acos_xx_a(TestTag::normal,"A",a,step); - ACosXX acos_xx_b(TestTag::sweep,"B",b,step); - ACosXX acos_xx_c(TestTag::sweep,"C",c,step); + ACosXX acos_xx_a(TestTags::standard(),"A",a,step); + ACosXX acos_xx_b(TestTags::sweep(),"B",b,step); + ACosXX acos_xx_c(TestTags::sweep(),"C",c,step); ATanXY atan_xy_a("A",a,step); ATanXY atan_xy_b("B",b,step); @@ -514,9 +514,9 @@ namespace Test { namespace Float { ATanXYSol atan_xy_sol_b("B",b,step); ATanXYSol atan_xy_sol_c("C",c,step); - ATanXX atan_xx_a(TestTag::normal,"A",a,step); - ATanXX atan_xx_b(TestTag::sweep,"B",b,step); - ATanXX atan_xx_c(TestTag::sweep,"C",c,step); + ATanXX atan_xx_a(TestTags::standard(),"A",a,step); + ATanXX atan_xx_b(TestTags::sweep(),"B",b,step); + ATanXX atan_xx_c(TestTags::sweep(),"C",c,step); //@} diff --git a/test/int.hpp b/test/int.hpp index a4324232eb..2c213ea685 100755 --- a/test/int.hpp +++ b/test/int.hpp @@ -175,7 +175,7 @@ namespace Test { namespace Int { Test::Test(const std::string& p, const std::string& s, int a, const Gecode::IntSet& d, bool r, Gecode::IntPropLevel i) - : Test(TestTag::normal,p,s,a,d,r,i) {} + : Test(TestTags::standard(),p,s,a,d,r,i) {} inline Test::Test(TestTags tags, const std::string& s, @@ -192,7 +192,7 @@ namespace Test { namespace Int { Test::Test(const std::string& s, int a, const Gecode::IntSet& d, bool r, Gecode::IntPropLevel i) - : Test(TestTag::normal,s,a,d,r,i) {} + : Test(TestTags::standard(),s,a,d,r,i) {} inline Test::Test(TestTags tags, const std::string& p, const std::string& s, @@ -209,7 +209,7 @@ namespace Test { namespace Int { Test::Test(const std::string& p, const std::string& s, int a, int min, int max, bool r, Gecode::IntPropLevel i) - : Test(TestTag::normal,p,s,a,min,max,r,i) {} + : Test(TestTags::standard(),p,s,a,min,max,r,i) {} inline Test::Test(TestTags tags, const std::string& s, @@ -224,7 +224,7 @@ namespace Test { namespace Int { inline Test::Test(const std::string& s, int a, int min, int max, bool r, Gecode::IntPropLevel i) - : Test(TestTag::normal,s,a,min,max,r,i) {} + : Test(TestTags::standard(),s,a,min,max,r,i) {} inline std::string diff --git a/test/int/arithmetic.cpp b/test/int/arithmetic.cpp index a3f6c63c38..0105cf41f7 100644 --- a/test/int/arithmetic.cpp +++ b/test/int/arithmetic.cpp @@ -2429,7 +2429,7 @@ namespace Test { namespace Int { /// Create and register test AbsXY(const std::string& s, const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test(TestTags(TestTag::normal,TestTag::check), + : Test(TestTags::check(), "Arithmetic::Abs::XY::"+str(ipl)+"::"+s,2,d,false,ipl) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -2449,7 +2449,7 @@ namespace Test { namespace Int { /// Create and register test AbsXX(const std::string& s, const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test(TestTags(TestTag::normal,TestTag::check), + : Test(TestTags::check(), "Arithmetic::Abs::XX::"+str(ipl)+"::"+s,1,d,false,ipl) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -2676,7 +2676,7 @@ namespace Test { namespace Int { public: /// Create and register test MaxNary(Gecode::IntPropLevel ipl) - : Test(TestTags(TestTag::normal,TestTag::check), + : Test(TestTags::check(), "Arithmetic::Max::Nary::"+str(ipl),4,-4,4,false,ipl) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -2695,7 +2695,7 @@ namespace Test { namespace Int { public: /// Create and register test MaxNaryShared(Gecode::IntPropLevel ipl) - : Test(TestTags(TestTag::normal,TestTag::check), + : Test(TestTags::check(), "Arithmetic::Max::Nary::Shared::"+str(ipl), 3,-4,4,false,ipl) {} /// %Test whether \a x is solution @@ -2720,7 +2720,7 @@ namespace Test { namespace Int { public: /// Create and register test ArgMax(int n, int o, bool tb) - : Test(TestTags(TestTag::normal,TestTag::check), + : Test(TestTags::check(), "Arithmetic::ArgMax::"+str(o)+"::"+str(tb)+"::"+str(n), n+1,0,n+1, false,tb ? Gecode::IPL_DEF : Gecode::IPL_DOM), @@ -2755,7 +2755,7 @@ namespace Test { namespace Int { public: /// Create and register test ArgMaxShared(int n, bool tb) - : Test(TestTags(TestTag::normal,TestTag::check), + : Test(TestTags::check(), "Arithmetic::ArgMax::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1, false), tiebreak(tb) { @@ -2870,7 +2870,7 @@ namespace Test { namespace Int { public: /// Create and register test ArgMaxBool(int n, int o, bool tb) - : Test(TestTags(TestTag::normal,TestTag::check), + : Test(TestTags::check(), "Arithmetic::ArgMaxBool::"+str(o)+"::"+str(tb)+"::"+str(n), n+1,0,n+1, false,tb ? Gecode::IPL_DEF : Gecode::IPL_DOM), @@ -2910,7 +2910,7 @@ namespace Test { namespace Int { public: /// Create and register test ArgMaxBoolShared(int n, bool tb) - : Test(TestTags(TestTag::normal,TestTag::check), + : Test(TestTags::check(), "Arithmetic::ArgMaxBool::Shared::"+str(tb)+"::"+str(n),n+1,0,n+1, false), tiebreak(tb) { @@ -3163,42 +3163,42 @@ namespace Test { namespace Int { for (int n=0; n<=6; n++) { TestTags distinct_tags = (n == 3) && (ipls.ipl() == Gecode::IPL_BND) - ? TestTag::normal : TestTag::sweep; - (void) new PowXY(TestTag::sweep,"A",n,a,ipls.ipl()); - (void) new PowXY(TestTag::sweep,"B",n,b,ipls.ipl()); + ? TestTags::standard() : TestTags::sweep(); + (void) new PowXY(TestTags::sweep(),"A",n,a,ipls.ipl()); + (void) new PowXY(TestTags::sweep(),"B",n,b,ipls.ipl()); (void) new PowXY(distinct_tags,"C",n,c,ipls.ipl()); - (void) new PowXY(TestTag::sweep,"D",n,d,ipls.ipl()); + (void) new PowXY(TestTags::sweep(),"D",n,d,ipls.ipl()); TestTags tags = (n == 0) && (ipls.ipl() == Gecode::IPL_BND) - ? TestTag::normal : TestTag::sweep; + ? TestTags::standard() : TestTags::sweep(); (void) new PowXX(tags,"A",n,a,ipls.ipl()); - (void) new PowXX(TestTag::sweep,"B",n,b,ipls.ipl()); - (void) new PowXX(TestTag::sweep,"C",n,c,ipls.ipl()); - (void) new PowXX(TestTag::sweep,"D",n,d,ipls.ipl()); + (void) new PowXX(TestTags::sweep(),"B",n,b,ipls.ipl()); + (void) new PowXX(TestTags::sweep(),"C",n,c,ipls.ipl()); + (void) new PowXX(TestTags::sweep(),"D",n,d,ipls.ipl()); } for (int n=1; n<=6; n++) { TestTags distinct_tags = (n == 3) && (ipls.ipl() == Gecode::IPL_BND) - ? TestTag::normal : TestTag::sweep; - (void) new NrootXY(TestTag::sweep,"A",n,a,ipls.ipl()); - (void) new NrootXY(TestTag::sweep,"B",n,b,ipls.ipl()); + ? TestTags::standard() : TestTags::sweep(); + (void) new NrootXY(TestTags::sweep(),"A",n,a,ipls.ipl()); + (void) new NrootXY(TestTags::sweep(),"B",n,b,ipls.ipl()); (void) new NrootXY(distinct_tags,"C",n,c,ipls.ipl()); - (void) new NrootXY(TestTag::sweep,"D",n,d,ipls.ipl()); + (void) new NrootXY(TestTags::sweep(),"D",n,d,ipls.ipl()); TestTags tags = (n == 1) && (ipls.ipl() == Gecode::IPL_BND) - ? TestTag::normal : TestTag::sweep; + ? TestTags::standard() : TestTags::sweep(); (void) new NrootXX(tags,"A",n,a,ipls.ipl()); - (void) new NrootXX(TestTag::sweep,"B",n,b,ipls.ipl()); - (void) new NrootXX(TestTag::sweep,"C",n,c,ipls.ipl()); - (void) new NrootXX(TestTag::sweep,"D",n,d,ipls.ipl()); + (void) new NrootXX(TestTags::sweep(),"B",n,b,ipls.ipl()); + (void) new NrootXX(TestTags::sweep(),"C",n,c,ipls.ipl()); + (void) new NrootXX(TestTags::sweep(),"D",n,d,ipls.ipl()); } for (int n=30; n<=34; n++) { - (void) new PowXY(TestTag::sweep,"C",n,c,ipls.ipl()); - (void) new PowXX(TestTag::sweep,"C",n,c,ipls.ipl()); - (void) new NrootXY(TestTag::sweep,"C",n,c,ipls.ipl()); - (void) new NrootXX(TestTag::sweep,"C",n,c,ipls.ipl()); + (void) new PowXY(TestTags::sweep(),"C",n,c,ipls.ipl()); + (void) new PowXX(TestTags::sweep(),"C",n,c,ipls.ipl()); + (void) new NrootXY(TestTags::sweep(),"C",n,c,ipls.ipl()); + (void) new NrootXX(TestTags::sweep(),"C",n,c,ipls.ipl()); } (void) new SqrtXY("A",a,ipls.ipl()); diff --git a/test/int/channel.cpp b/test/int/channel.cpp index abb7b9e6c2..9811caabc8 100644 --- a/test/int/channel.cpp +++ b/test/int/channel.cpp @@ -53,7 +53,7 @@ namespace Test { namespace Int { public: /// Construct and register test ChannelFull(int xoff0, int yoff0, Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"Channel::Full::"+str(xoff0)+"::"+str(yoff0)+"::"+str(ipl), + : Test(TestTags::sweep(),"Channel::Full::"+str(xoff0)+"::"+str(yoff0)+"::"+str(ipl), 8,0,3,false,ipl), xoff(xoff0), yoff(yoff0) { contest = CTL_NONE; @@ -94,7 +94,7 @@ namespace Test { namespace Int { public: /// Construct and register test ChannelHalf(Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"Channel::Half::"+str(ipl),6,0,5,false,ipl) { + : Test(TestTags::sweep(),"Channel::Half::"+str(ipl),6,0,5,false,ipl) { contest = CTL_NONE; } /// Check whether \a x is solution @@ -124,7 +124,7 @@ namespace Test { namespace Int { public: /// Construct and register test ChannelShared(Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"Channel::Shared::"+str(ipl),6,0,5,false,ipl) { + : Test(TestTags::sweep(),"Channel::Shared::"+str(ipl),6,0,5,false,ipl) { contest = CTL_NONE; } /// Check whether \a x is solution @@ -146,7 +146,7 @@ namespace Test { namespace Int { public: /// Construct and register test ChannelLinkSingle(void) - : Test(TestTag::sweep,"Channel::Bool::Single",2,-1,2) { + : Test(TestTags::sweep(),"Channel::Bool::Single",2,-1,2) { contest = CTL_NONE; } /// Check whether \a x is solution @@ -219,9 +219,9 @@ namespace Test { namespace Int { ChannelLinkSingle cls; - ChannelLinkMulti clma(TestTag::normal,"A", 0, 5, 0); - ChannelLinkMulti clmb(TestTag::sweep,"B", 1, 6, 1); - ChannelLinkMulti clmc(TestTag::sweep,"C",-1, 4,-1); + ChannelLinkMulti clma(TestTags::standard(),"A", 0, 5, 0); + ChannelLinkMulti clmb(TestTags::sweep(),"B", 1, 6, 1); + ChannelLinkMulti clmc(TestTags::sweep(),"C",-1, 4,-1); //@} } diff --git a/test/int/circuit.cpp b/test/int/circuit.cpp index b274321a85..c087f0d575 100644 --- a/test/int/circuit.cpp +++ b/test/int/circuit.cpp @@ -52,7 +52,7 @@ namespace Test { namespace Int { public: /// Create and register test Circuit(int n, int min, int max, int off, Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"Circuit::" + str(ipl) + "::" + str(n) + "::" + str(off), + : Test(TestTags::sweep(),"Circuit::" + str(ipl) + "::" + str(n) + "::" + str(off), n,min,max,false,ipl), offset(off) { contest = CTL_NONE; testfix = false; @@ -95,7 +95,7 @@ namespace Test { namespace Int { public: /// Create and register test Path(int n, int min, int max, int off, Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"Path::" + str(ipl) + "::" + str(n) + "::" + str(off), + : Test(TestTags::sweep(),"Path::" + str(ipl) + "::" + str(n) + "::" + str(off), n+2,min,max,false,ipl), offset(off) { contest = CTL_NONE; testfix = false; @@ -149,7 +149,7 @@ namespace Test { namespace Int { /// Create and register test CircuitCost(int n, int min, int max, int off, Gecode::IntPropLevel ipl) : Test((ipl == Gecode::IPL_DOM) && (n == 4) && (off == 0) - ? TestTag::normal : TestTag::sweep, + ? TestTags::standard() : TestTags::sweep(), "Circuit::Cost::"+str(ipl)+"::"+str(n)+"::"+str(off), n+1,min,max,false,ipl), offset(off) { contest = CTL_NONE; @@ -206,7 +206,7 @@ namespace Test { namespace Int { /// Create and register test PathCost(int n, int min, int max, int off, Gecode::IntPropLevel ipl) : Test((ipl == Gecode::IPL_DOM) && (n == 3) && (off == 0) - ? TestTag::normal : TestTag::sweep, + ? TestTags::standard() : TestTags::sweep(), "Path::Cost::"+str(ipl)+"::"+str(n)+"::"+str(off), n+3,min,max,false,ipl), offset(off) { contest = CTL_NONE; @@ -270,7 +270,7 @@ namespace Test { namespace Int { /// Create and register test CircuitFullCost(int n, int min, int max, int off, Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"Circuit::FullCost::" + str(ipl)+"::"+str(n)+"::"+str(off), + : Test(TestTags::sweep(),"Circuit::FullCost::" + str(ipl)+"::"+str(n)+"::"+str(off), 2*n+1,min,max,false,ipl), offset(off) { contest = CTL_NONE; testfix = false; diff --git a/test/int/cumulative.cpp b/test/int/cumulative.cpp index e83cfdecab..ab4ade9a53 100755 --- a/test/int/cumulative.cpp +++ b/test/int/cumulative.cpp @@ -77,8 +77,8 @@ namespace Test { namespace Int { int o0, Gecode::IntPropLevel ipl0) : Test((o0 == 0) && (c0 == 4) - ? TestTags(TestTag::normal,TestTag::check) - : TestTags(TestTag::sweep), + ? TestTags::check() + : TestTags(TestTags::sweep()), "Cumulative::Man::Fix::"+str(o0)+"::"+ str(c0)+"::"+str(p0)+"::"+str(u0)+"::"+str(ipl0), (c0 >= 0) ? p0.size():p0.size()+1,0,st(c0,p0,u0),false,ipl0), @@ -183,7 +183,7 @@ namespace Test { namespace Int { int o0, Gecode::IntPropLevel ipl0) : Test((o0 == Gecode::Int::Limits::min) && (c0 == -1) - ? TestTags(TestTag::normal) : TestTags(TestTag::sweep), + ? TestTags(TestTags::standard()) : TestTags(TestTags::sweep()), "Cumulative::Opt::Fix::"+str(o0)+"::"+ str(c0)+"::"+str(p0)+"::"+str(u0)+"::"+str(ipl0), (c0 >= 0) ? 2*p0.size() : 2*p0.size()+1,0,st(c0,p0,u0), @@ -290,7 +290,7 @@ namespace Test { namespace Int { const Gecode::IntArgs& u0, int o0, Gecode::IntPropLevel ipl0) - : Test(TestTag::sweep,"Cumulative::Man::Flex::"+str(o0)+"::"+ + : Test(TestTags::sweep(),"Cumulative::Man::Flex::"+str(o0)+"::"+ str(c0)+"::"+str(minP)+"::"+str(maxP)+"::"+str(u0)+ "::"+str(ipl0), (c0 >= 0) ? 2*u0.size() : 2*u0.size()+1, @@ -405,7 +405,7 @@ namespace Test { namespace Int { Gecode::IntPropLevel ipl0) : Test((o0 == Gecode::Int::Limits::min) && (c0 == 4) && (minP == 0) && (maxP == 2) - ? TestTags(TestTag::normal) : TestTags(TestTag::sweep), + ? TestTags(TestTags::standard()) : TestTags(TestTags::sweep()), "Cumulative::Opt::Flex::"+str(o0)+"::"+ str(c0)+"::"+str(minP)+"::"+str(maxP)+"::"+str(u0)+ "::"+str(ipl0), diff --git a/test/int/distinct.cpp b/test/int/distinct.cpp index 182e7076fc..6859aca611 100755 --- a/test/int/distinct.cpp +++ b/test/int/distinct.cpp @@ -54,13 +54,13 @@ namespace Test { namespace Int { Distinct(const Gecode::IntSet& d0, Gecode::IntPropLevel ipl, int n=6) : Test((useCount || (ipl != Gecode::IPL_VAL)) - ? TestTag::sweep : TestTag::normal, + ? TestTags::sweep() : TestTags::standard(), std::string(useCount ? "Count::Distinct::" : "Distinct::")+ str(ipl)+"::Sparse::"+str(n),n,d0,false,ipl) {} /// Create and register test Distinct(int min, int max, Gecode::IntPropLevel ipl) : Test((!useCount || (ipl == Gecode::IPL_BND)) - ? TestTag::normal : TestTag::sweep, + ? TestTags::standard() : TestTags::sweep(), std::string(useCount ? "Count::Distinct::" : "Distinct::")+ str(ipl)+"::Dense",6,min,max,false,ipl) {} /// Check whether \a x is solution @@ -91,11 +91,11 @@ namespace Test { namespace Int { public: /// Create and register test Offset(const Gecode::IntSet& d, Gecode::IntPropLevel ipl) - : Test(TestTag::sweep, + : Test(TestTags::sweep(), "Distinct::Offset::Sparse::"+str(ipl),6,d,false,ipl) {} /// Create and register test Offset(int min, int max, Gecode::IntPropLevel ipl) - : Test(ipl == Gecode::IPL_BND ? TestTag::normal : TestTag::sweep, + : Test(ipl == Gecode::IPL_BND ? TestTags::standard() : TestTags::sweep(), "Distinct::Offset::Dense::"+str(ipl),6,min,max,false,ipl) {} /// Check whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -174,7 +174,7 @@ namespace Test { namespace Int { public: /// Create and register test Random(int n, int min, int max, Gecode::IntPropLevel ipl) - : Test(TestTags(TestTag::normal,TestTag::check), + : Test(TestTags::check(), "Distinct::Random::"+str(ipl),n,min,max,false,ipl) { testsearch = false; } @@ -220,7 +220,7 @@ namespace Test { namespace Int { /// Create and register test Pathological(int n0, Gecode::IntPropLevel ipl0) : Base("Int::Distinct::Pathological::"+ - Test::str(n0)+"::"+Test::str(ipl0), TestTag::sweep), + Test::str(n0)+"::"+Test::str(ipl0), TestTags::sweep()), n(n0), ipl(ipl0) {} /// Perform test virtual bool run(void) { diff --git a/test/int/extensional.cpp b/test/int/extensional.cpp index 53dc0a1513..5de3aa3d86 100755 --- a/test/int/extensional.cpp +++ b/test/int/extensional.cpp @@ -567,7 +567,7 @@ namespace Test { namespace Int { public: /// Create and register test RegRandomNFADifferential(unsigned int seed) - : Test(TestTags(TestTag::normal,TestTag::check), + : Test(TestTags::check(), "Extensional::Reg::Sparse::RandomNFADifferential::" + Test::str(static_cast(seed)), 5,0,n_symbols-1,false,Gecode::IPL_DOM) { @@ -641,7 +641,7 @@ namespace Test { namespace Int { public: /// Create and register test RegNFAPrefix(bool b) - : Test(TestTags(TestTag::normal,TestTag::check), + : Test(TestTags::check(), "Extensional::Reg::Sparse::NFAPrefix::" + std::string(b ? "Bool" : "Int"), 5,0,1,false,Gecode::IPL_DOM), boolean(b) {} @@ -829,7 +829,7 @@ namespace Test { namespace Int { public: /// Create and register test TupleSetBase(bool p, Gecode::ExtensionalPropKind epk0) - : Test(TestTag::sweep, + : Test(TestTags::sweep(), "Extensional::TupleSet::" + extensional_kind_name(epk0) + "::" + str(p) + "::Base", 4,1,5,true,Gecode::IPL_DOM), @@ -889,7 +889,7 @@ namespace Test { namespace Int { TupleSetTest(const std::string& s, bool p, Gecode::IntSet d0, Gecode::TupleSet ts0, bool td, Gecode::ExtensionalPropKind epk0) - : Test(TestTag::sweep, + : Test(TestTags::sweep(), "Extensional::TupleSet::" + extensional_kind_name(epk0) + "::" + str(p) + "::" + s, ts0.arity(),d0,true,Gecode::IPL_DOM), @@ -1176,7 +1176,7 @@ namespace Test { namespace Int { SparseTupleSetIncrementalDelta(void) : ::Test::Base( "Int::Extensional::TupleSet::Sparse::IncrementalDelta", - TestTags(TestTag::normal,TestTag::check)) {} + TestTags::check()) {} virtual bool run(void) { using namespace Gecode; @@ -1861,7 +1861,7 @@ namespace Test { namespace Int { TupleSetAutoDefaultDispatch(void) : ::Test::Base( "Int::Extensional::TupleSet::Auto::DefaultDispatch", - TestTags(TestTag::normal,TestTag::check)) {} + TestTags::check()) {} virtual bool run(void) { using namespace Gecode; @@ -2236,7 +2236,7 @@ namespace Test { namespace Int { public: /// Create and register test TupleSetLarge(double prob, bool p, Gecode::ExtensionalPropKind epk0) - : Test(TestTag::sweep, + : Test(TestTags::sweep(), "Extensional::TupleSet::" + extensional_kind_name(epk0) + "::" + str(p) + "::Large", 5,1,5,true,Gecode::IPL_DOM), @@ -2292,7 +2292,7 @@ namespace Test { namespace Int { public: /// Create and register test TupleSetBool(double prob, bool p, Gecode::ExtensionalPropKind epk0) - : Test(TestTag::sweep, + : Test(TestTags::sweep(), "Extensional::TupleSet::" + extensional_kind_name(epk0) + "::" + str(p) + "::Bool", 5,0,1,true), pos(p), epk(epk0), t(5) { diff --git a/test/int/gcc.cpp b/test/int/gcc.cpp index 900cb10110..e0ecd35c5f 100755 --- a/test/int/gcc.cpp +++ b/test/int/gcc.cpp @@ -52,7 +52,7 @@ namespace Test { namespace Int { public: /// Create and register test IntAllMinMax(Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"GCC::Int::All::MinMax::"+str(ipl),4,-1,3,false,ipl) {} + : Test(TestTags::sweep(),"GCC::Int::All::MinMax::"+str(ipl),4,-1,3,false,ipl) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { int n[5]; @@ -86,7 +86,7 @@ namespace Test { namespace Int { public: /// Create and register test IntAllMinMaxDef(Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"GCC::Int::All::MinMaxDef::"+str(ipl),4,0,3,false,ipl) {} + : Test(TestTags::sweep(),"GCC::Int::All::MinMaxDef::"+str(ipl),4,0,3,false,ipl) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { int n[4]; @@ -119,7 +119,7 @@ namespace Test { namespace Int { public: /// Create and register test IntAllMax(Gecode::IntPropLevel ipl) - : Test(ipl == Gecode::IPL_BND ? TestTag::normal : TestTag::sweep, + : Test(ipl == Gecode::IPL_BND ? TestTags::standard() : TestTags::sweep(), "GCC::Int::All::Max::"+str(ipl), 4, 1,2, false, ipl) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -146,7 +146,7 @@ namespace Test { namespace Int { public: /// Create and register test IntSome(Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,std::string("GCC::Int::Some::")+ + : Test(TestTags::sweep(),std::string("GCC::Int::Some::")+ (hole ? "::Hole" : "::Full")+str(ipl),4,1,4,false,ipl) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { @@ -184,7 +184,7 @@ namespace Test { namespace Int { public: /// Create and register test VarAll(Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"GCC::Var::All::"+str(ipl),7,0,2,false,ipl) {} + : Test(TestTags::sweep(),"GCC::Var::All::"+str(ipl),7,0,2,false,ipl) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { // Number of cardinality variables @@ -236,7 +236,7 @@ namespace Test { namespace Int { /// Create and register test VarSome(std::string s, int n0, int min, int max, Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"GCC::Var::Some::"+s+"::"+str(ipl), + : Test(TestTags::sweep(),"GCC::Var::Some::"+s+"::"+str(ipl), n0+(max-min)+1,min,max,false,ipl) , n(n0) { diff --git a/test/int/linear.cpp b/test/int/linear.cpp index 6b8706b796..05867ef5e6 100755 --- a/test/int/linear.cpp +++ b/test/int/linear.cpp @@ -110,7 +110,7 @@ namespace Test { namespace Int { IntVar(const std::string& s, const Gecode::IntSet& d, const Gecode::IntArgs& a0, Gecode::IntRelType irt0, Gecode::IntPropLevel ipl=Gecode::IPL_BND) - : Test(TestTag::sweep,"Linear::Int::Var::"+ + : Test(TestTags::sweep(),"Linear::Int::Var::"+ str(irt0)+"::"+str(ipl)+"::"+s+"::"+str(a0.size()), a0.size()+1,d,ipl != Gecode::IPL_DOM,ipl), a(a0), irt(irt0) { @@ -162,8 +162,8 @@ namespace Test { namespace Int { BoolInt(const std::string& s, const Gecode::IntArgs& a0, Gecode::IntRelType irt0, int c0) : Test(irt0 == Gecode::IRT_LQ - ? TestTags(TestTag::normal,TestTag::check) - : TestTags(TestTag::sweep),"Linear::Bool::Int::"+ + ? TestTags::check() + : TestTags(TestTags::sweep()),"Linear::Bool::Int::"+ str(irt0)+"::"+s+"::"+str(a0.size())+"::"+str(c0), a0.size(),0,1,true,Gecode::IPL_DEF), a(a0), irt(irt0), c(c0) { @@ -211,7 +211,7 @@ namespace Test { namespace Int { BoolVar(const std::string& s, int min, int max, const Gecode::IntArgs& a0, Gecode::IntRelType irt0) - : Test(TestTag::sweep,"Linear::Bool::Var::"+str(irt0)+"::"+s,a0.size()+1, + : Test(TestTags::sweep(),"Linear::Bool::Var::"+str(irt0)+"::"+s,a0.size()+1, min,max,true), a(a0), irt(irt0) { testfix=false; @@ -277,16 +277,16 @@ namespace Test { namespace Int { for (IntRelTypes irts; irts(); ++irts) { TestTags tags = irts.irt() == Gecode::IRT_EQ - ? TestTag::normal : TestTag::sweep; + ? TestTags::standard() : TestTags::sweep(); (void) new IntInt(tags,"11",d1,a1,irts.irt(),0); (void) new IntVar("11",d1,a1,irts.irt()); - (void) new IntInt(TestTag::sweep,"21",d2,a1,irts.irt(),0); + (void) new IntInt(TestTags::sweep(),"21",d2,a1,irts.irt(),0); (void) new IntVar("21",d2,a1,irts.irt()); - (void) new IntInt(TestTag::sweep,"31",d3,a1,irts.irt(),150000000); + (void) new IntInt(TestTags::sweep(),"31",d3,a1,irts.irt(),150000000); } - (void) new IntInt(TestTag::sweep,"11",d1,a1,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTags::sweep(),"11",d1,a1,IRT_EQ,0,IPL_DOM); (void) new IntVar("11",d1,a1,IRT_EQ,IPL_DOM); - (void) new IntInt(TestTag::sweep,"21",d2,a1,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTags::sweep(),"21",d2,a1,IRT_EQ,0,IPL_DOM); (void) new IntVar("21",d2,a1,IRT_EQ,IPL_DOM); const int av2[5] = {1,1,1,1,1}; @@ -301,15 +301,15 @@ namespace Test { namespace Int { IntArgs a4(i, av4); IntArgs a5(i, av5); for (IntRelTypes irts; irts(); ++irts) { - (void) new IntInt(TestTag::sweep,"12",d1,a2,irts.irt(),0); - (void) new IntInt(TestTag::sweep,"13",d1,a3,irts.irt(),0); - (void) new IntInt(TestTag::sweep,"14",d1,a4,irts.irt(),0); - (void) new IntInt(TestTag::sweep,"15",d1,a5,irts.irt(),0); - (void) new IntInt(TestTag::sweep,"22",d2,a2,irts.irt(),0); - (void) new IntInt(TestTag::sweep,"23",d2,a3,irts.irt(),0); - (void) new IntInt(TestTag::sweep,"24",d2,a4,irts.irt(),0); - (void) new IntInt(TestTag::sweep,"25",d2,a5,irts.irt(),0); - (void) new IntInt(TestTag::sweep,"32",d3,a2,irts.irt(),1500000000); + (void) new IntInt(TestTags::sweep(),"12",d1,a2,irts.irt(),0); + (void) new IntInt(TestTags::sweep(),"13",d1,a3,irts.irt(),0); + (void) new IntInt(TestTags::sweep(),"14",d1,a4,irts.irt(),0); + (void) new IntInt(TestTags::sweep(),"15",d1,a5,irts.irt(),0); + (void) new IntInt(TestTags::sweep(),"22",d2,a2,irts.irt(),0); + (void) new IntInt(TestTags::sweep(),"23",d2,a3,irts.irt(),0); + (void) new IntInt(TestTags::sweep(),"24",d2,a4,irts.irt(),0); + (void) new IntInt(TestTags::sweep(),"25",d2,a5,irts.irt(),0); + (void) new IntInt(TestTags::sweep(),"32",d3,a2,irts.irt(),1500000000); if (i < 5) { (void) new IntVar("12",d1,a2,irts.irt()); (void) new IntVar("13",d1,a3,irts.irt()); @@ -321,14 +321,14 @@ namespace Test { namespace Int { (void) new IntVar("25",d2,a5,irts.irt()); } } - (void) new IntInt(TestTag::sweep,"12",d1,a2,IRT_EQ,0,IPL_DOM); - (void) new IntInt(TestTag::sweep,"13",d1,a3,IRT_EQ,0,IPL_DOM); - (void) new IntInt(TestTag::sweep,"14",d1,a4,IRT_EQ,0,IPL_DOM); - (void) new IntInt(TestTag::sweep,"15",d1,a5,IRT_EQ,0,IPL_DOM); - (void) new IntInt(TestTag::sweep,"22",d2,a2,IRT_EQ,0,IPL_DOM); - (void) new IntInt(TestTag::sweep,"23",d2,a3,IRT_EQ,0,IPL_DOM); - (void) new IntInt(TestTag::sweep,"24",d2,a4,IRT_EQ,0,IPL_DOM); - (void) new IntInt(TestTag::sweep,"25",d2,a5,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTags::sweep(),"12",d1,a2,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTags::sweep(),"13",d1,a3,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTags::sweep(),"14",d1,a4,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTags::sweep(),"15",d1,a5,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTags::sweep(),"22",d2,a2,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTags::sweep(),"23",d2,a3,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTags::sweep(),"24",d2,a4,IRT_EQ,0,IPL_DOM); + (void) new IntInt(TestTags::sweep(),"25",d2,a5,IRT_EQ,0,IPL_DOM); if (i < 4) { (void) new IntVar("12",d1,a2,IRT_EQ,IPL_DOM); (void) new IntVar("13",d1,a3,IRT_EQ,IPL_DOM); diff --git a/test/int/mm-lin.cpp b/test/int/mm-lin.cpp index 4cbd1db91c..e1603a1c5e 100755 --- a/test/int/mm-lin.cpp +++ b/test/int/mm-lin.cpp @@ -140,7 +140,7 @@ namespace Test { namespace Int { public: /// Create and register test LinExprInt(const LinInstr* lis0, const std::string& s) - : Test(TestTag::sweep,"MiniModel::LinExpr::Int::"+s,4,-3,3), + : Test(TestTags::sweep(),"MiniModel::LinExpr::Int::"+s,4,-3,3), lis(lis0) { testfix = false; } @@ -195,7 +195,7 @@ namespace Test { namespace Int { public: /// Create and register test LinExprMixed(const LinInstr* lis0, const std::string& s) - : Test(TestTag::sweep,"MiniModel::LinExpr::Mixed::"+s,4,-3,3), + : Test(TestTags::sweep(),"MiniModel::LinExpr::Mixed::"+s,4,-3,3), lis(lis0) { testfix = false; } @@ -2197,8 +2197,8 @@ namespace Test { namespace Int { } (void) new LinExprInt(li[i],s); TestTags bool_tags = (i == 352) - ? TestTags(TestTag::normal,TestTag::check) - : TestTags(TestTag::sweep); + ? TestTags::check() + : TestTags(TestTags::sweep()); (void) new LinExprBool(bool_tags,li[i],s); (void) new LinExprMixed(li[i],s); } diff --git a/test/int/no-overlap.cpp b/test/int/no-overlap.cpp index 069a143ae2..67298feeea 100755 --- a/test/int/no-overlap.cpp +++ b/test/int/no-overlap.cpp @@ -97,7 +97,7 @@ namespace Test { namespace Int { public: /// Create and register test with maximal value \a m and \a n rectangles IntOpt2(int m, const Gecode::IntArgs& w0, const Gecode::IntArgs& h0) - : Test(TestTag::sweep,"NoOverlap::Int::Opt::2::"+str(m)+"::"+str(w0)+"::"+str(h0), + : Test(TestTags::sweep(),"NoOverlap::Int::Opt::2::"+str(m)+"::"+str(w0)+"::"+str(h0), 3*w0.size(), 0, m-1), w(w0), h(h0) {} /// %Test whether \a xyo is solution virtual bool solution(const Assignment& xyo) const { @@ -135,7 +135,7 @@ namespace Test { namespace Int { public: /// Create and register test with maximal value \a m and \a n rectangles Var2(int m, int n) - : Test(TestTag::sweep,"NoOverlap::Var::2::"+str(m)+"::"+str(n), 4*n, 0, m) {} + : Test(TestTags::sweep(),"NoOverlap::Var::2::"+str(m)+"::"+str(n), 4*n, 0, m) {} /// %Test whether \a xwyh is solution virtual bool solution(const Assignment& xwyh) const { int n = xwyh.size() / 4; @@ -172,7 +172,7 @@ namespace Test { namespace Int { public: /// Create and register test with maximal value \a m and \a n rectangles VarOpt2(int m, int n) - : Test(TestTag::sweep,"NoOverlap::Var::Opt::2::"+str(m)+"::"+str(n), 5*n, 0, m) { + : Test(TestTags::sweep(),"NoOverlap::Var::Opt::2::"+str(m)+"::"+str(n), 5*n, 0, m) { testfix = false; } /// %Test whether \a xwyho is solution @@ -216,7 +216,7 @@ namespace Test { namespace Int { public: /// Create and register test with maximal value \a m and \a n rectangles VarOptShared2(int m, int n) - : Test(TestTag::sweep,"NoOverlap::Var::Opt::Shared::2::"+ + : Test(TestTags::sweep(),"NoOverlap::Var::Opt::Shared::2::"+ str(m)+"::"+str(n), 2*n+2, 0, m) { testfix = false; } @@ -270,12 +270,12 @@ namespace Test { namespace Int { IntArgs s4({1,1,1,1}); for (int m=2; m<3; m++) { - (void) new Int2(TestTag::sweep,m,s1,s1); - (void) new Int2(TestTag::sweep,m,s2,s2); - (void) new Int2(TestTag::sweep,m,s3,s3); - (void) new Int2(TestTag::sweep,m,s2,s3); - (void) new Int2(TestTag::normal,m,s4,s4); - (void) new Int2(TestTag::sweep,m,s4,s2); + (void) new Int2(TestTags::sweep(),m,s1,s1); + (void) new Int2(TestTags::sweep(),m,s2,s2); + (void) new Int2(TestTags::sweep(),m,s3,s3); + (void) new Int2(TestTags::sweep(),m,s2,s3); + (void) new Int2(TestTags::standard(),m,s4,s4); + (void) new Int2(TestTags::sweep(),m,s4,s2); (void) new IntOpt2(m, s2, s3); (void) new IntOpt2(m, s4, s3); } diff --git a/test/int/nvalues.cpp b/test/int/nvalues.cpp index 4b81a4c2b5..c6eeef410a 100644 --- a/test/int/nvalues.cpp +++ b/test/int/nvalues.cpp @@ -223,13 +223,13 @@ namespace Test { namespace Int { for (int m=0; m<=i+1; m++) { TestTags tags = ((i == 3) && (m == 2) && (irts.irt() == Gecode::IRT_EQ)) - ? TestTag::normal : TestTag::sweep; + ? TestTags::standard() : TestTags::sweep(); (void) new IntInt(tags,i,m,irts.irt()); } if (i <= 5) { TestTags tags = ((i == 3) && (irts.irt() == Gecode::IRT_EQ)) - ? TestTag::normal : TestTag::sweep; + ? TestTags::standard() : TestTags::sweep(); (void) new IntVar(tags,i,irts.irt()); } } diff --git a/test/int/rel.cpp b/test/int/rel.cpp index 733f1b3792..652067691d 100755 --- a/test/int/rel.cpp +++ b/test/int/rel.cpp @@ -53,7 +53,7 @@ namespace Test { namespace Int { public: /// Create and register test IntVarXY(Gecode::IntRelType irt0, int n, Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"Rel::Int::Var::XY::"+str(irt0)+"::"+str(ipl)+"::"+str(n), + : Test(TestTags::sweep(),"Rel::Int::Var::XY::"+str(irt0)+"::"+str(ipl)+"::"+str(n), n+1,-3,3,n==1,ipl), irt(irt0) {} /// %Test whether \a x is solution @@ -91,7 +91,7 @@ namespace Test { namespace Int { public: /// Create and register test IntVarXX(Gecode::IntRelType irt0, Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"Rel::Int::Var::XX::"+str(irt0)+"::"+str(ipl), + : Test(TestTags::sweep(),"Rel::Int::Var::XX::"+str(irt0)+"::"+str(ipl), 1,-3,3,true,ipl), irt(irt0) { contest = ((irt != Gecode::IRT_LE) && @@ -191,7 +191,7 @@ namespace Test { namespace Int { public: /// Create and register test IntInt(Gecode::IntRelType irt0, int n, int c0) - : Test(TestTag::sweep,"Rel::Int::Int::"+str(irt0)+"::"+str(n)+"::"+str(c0), + : Test(TestTags::sweep(),"Rel::Int::Int::"+str(irt0)+"::"+str(n)+"::"+str(c0), n,-3,3,n==1), irt(irt0), c(c0) {} /// %Test whether \a x is solution @@ -265,7 +265,7 @@ namespace Test { namespace Int { public: /// Create and register test IntSeq(int n, Gecode::IntRelType irt0, Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"Rel::Int::Seq::"+str(n)+"::"+str(irt0)+"::"+str(ipl), + : Test(TestTags::sweep(),"Rel::Int::Seq::"+str(n)+"::"+str(irt0)+"::"+str(ipl), n,-3,3,false,ipl), irt(irt0) {} /// %Test whether \a x is solution @@ -298,7 +298,7 @@ namespace Test { namespace Int { public: /// Create and register test IntSharedSeq(int n, Gecode::IntRelType irt0, Gecode::IntPropLevel ipl) - : Test(TestTag::sweep,"Rel::Int::Seq::Shared::"+str(n)+"::"+str(irt0)+"::"+str(ipl), + : Test(TestTags::sweep(),"Rel::Int::Seq::Shared::"+str(n)+"::"+str(irt0)+"::"+str(ipl), n,-3,3,false,ipl), irt(irt0) {} /// %Test whether \a x is solution @@ -411,7 +411,7 @@ namespace Test { namespace Int { public: /// Create and register test IntArrayVar(Gecode::IntRelType irt0) - : Test(TestTag::sweep,"Rel::Int::Array::Var::"+str(irt0),6,-2,2), irt(irt0) {} + : Test(TestTags::sweep(),"Rel::Int::Array::Var::"+str(irt0),6,-2,2), irt(irt0) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { int n=x.size() >> 1; @@ -443,7 +443,7 @@ namespace Test { namespace Int { public: /// Create and register test IntArrayInt(Gecode::IntRelType irt0) - : Test(TestTag::sweep,"Rel::Int::Array::Int::"+str(irt0),3,-2,2), irt(irt0) {} + : Test(TestTags::sweep(),"Rel::Int::Array::Int::"+str(irt0),3,-2,2), irt(irt0) {} /// %Test whether \a x is solution virtual bool solution(const Assignment& x) const { Gecode::IntArgs y({0,0,0}); @@ -477,7 +477,7 @@ namespace Test { namespace Int { /// Create and register test IntArrayDiff(Gecode::IntRelType irt0, int m) : Test((irt0 == Gecode::IRT_EQ) && (m == 0) - ? TestTag::normal : TestTag::sweep, + ? TestTags::standard() : TestTags::sweep(), "Rel::Int::Array::"+str(irt0)+"::"+str(m)+"::"+str(n-m), n,-2,2), irt(irt0), n_fst(m) { diff --git a/test/int/unary.cpp b/test/int/unary.cpp index 2cbc925815..0d7fd01b5e 100755 --- a/test/int/unary.cpp +++ b/test/int/unary.cpp @@ -273,62 +273,62 @@ namespace Test { namespace Int { namespace Unary { for (IntPropBasicAdvanced ipba; ipba(); ++ipba) { TestTags representative = ipba.ipl() == Gecode::IPL_ADVANCED - ? TestTag::normal : TestTag::sweep; - (void) new ManFixPUnary(TestTag::sweep,p1,0,ipba.ipl()); - (void) new ManFixPUnary(TestTag::sweep,p1,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFixPUnary(TestTag::sweep,p1,0,ipba.ipl()); - (void) new OptFixPUnary(TestTag::sweep,p1,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,4,0,2,0,ipba.ipl()); + ? TestTags::standard() : TestTags::sweep(); + (void) new ManFixPUnary(TestTags::sweep(),p1,0,ipba.ipl()); + (void) new ManFixPUnary(TestTags::sweep(),p1,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFixPUnary(TestTags::sweep(),p1,0,ipba.ipl()); + (void) new OptFixPUnary(TestTags::sweep(),p1,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),4,0,2,0,ipba.ipl()); (void) new ManFlexUnary(representative,4,0,2,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,4,1,3,0,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,4,1,3,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFlexUnary(TestTag::sweep,4,0,2,0,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),4,1,3,0,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),4,1,3,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFlexUnary(TestTags::sweep(),4,0,2,0,ipba.ipl()); (void) new OptFlexUnary(representative,4,0,2,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFixPUnary(TestTag::sweep,p10,0,ipba.ipl()); + (void) new ManFixPUnary(TestTags::sweep(),p10,0,ipba.ipl()); (void) new ManFixPUnary(representative,p10,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFixPUnary(TestTag::sweep,p10,0,ipba.ipl()); + (void) new OptFixPUnary(TestTags::sweep(),p10,0,ipba.ipl()); (void) new OptFixPUnary(representative,p10,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,5,0,2,0,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,5,0,2,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFlexUnary(TestTag::sweep,5,0,2,0,ipba.ipl()); - (void) new OptFlexUnary(TestTag::sweep,5,0,2,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),5,0,2,0,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),5,0,2,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFlexUnary(TestTags::sweep(),5,0,2,0,ipba.ipl()); + (void) new OptFlexUnary(TestTags::sweep(),5,0,2,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFixPUnary(TestTag::sweep,p2,0,ipba.ipl()); - (void) new ManFixPUnary(TestTag::sweep,p2,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFixPUnary(TestTag::sweep,p2,0,ipba.ipl()); - (void) new OptFixPUnary(TestTag::sweep,p2,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,4,3,5,0,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,4,3,5,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFlexUnary(TestTag::sweep,4,3,5,0,ipba.ipl()); - (void) new OptFlexUnary(TestTag::sweep,4,3,5,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFixPUnary(TestTags::sweep(),p2,0,ipba.ipl()); + (void) new ManFixPUnary(TestTags::sweep(),p2,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFixPUnary(TestTags::sweep(),p2,0,ipba.ipl()); + (void) new OptFixPUnary(TestTags::sweep(),p2,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),4,3,5,0,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),4,3,5,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFlexUnary(TestTags::sweep(),4,3,5,0,ipba.ipl()); + (void) new OptFlexUnary(TestTags::sweep(),4,3,5,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFixPUnary(TestTag::sweep,p20,0,ipba.ipl()); - (void) new ManFixPUnary(TestTag::sweep,p20,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFixPUnary(TestTag::sweep,p20,0,ipba.ipl()); - (void) new OptFixPUnary(TestTag::sweep,p20,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,6,0,5,0,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,6,0,5,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFlexUnary(TestTag::sweep,6,0,5,0,ipba.ipl()); - (void) new OptFlexUnary(TestTag::sweep,6,0,5,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFixPUnary(TestTags::sweep(),p20,0,ipba.ipl()); + (void) new ManFixPUnary(TestTags::sweep(),p20,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFixPUnary(TestTags::sweep(),p20,0,ipba.ipl()); + (void) new OptFixPUnary(TestTags::sweep(),p20,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),6,0,5,0,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),6,0,5,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFlexUnary(TestTags::sweep(),6,0,5,0,ipba.ipl()); + (void) new OptFlexUnary(TestTags::sweep(),6,0,5,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFixPUnary(TestTag::sweep,p3,0,ipba.ipl()); - (void) new ManFixPUnary(TestTag::sweep,p3,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFixPUnary(TestTag::sweep,p3,0,ipba.ipl()); - (void) new OptFixPUnary(TestTag::sweep,p3,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,6,2,7,0,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,6,2,7,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFlexUnary(TestTag::sweep,6,2,7,0,ipba.ipl()); - (void) new OptFlexUnary(TestTag::sweep,6,2,7,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFixPUnary(TestTags::sweep(),p3,0,ipba.ipl()); + (void) new ManFixPUnary(TestTags::sweep(),p3,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFixPUnary(TestTags::sweep(),p3,0,ipba.ipl()); + (void) new OptFixPUnary(TestTags::sweep(),p3,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),6,2,7,0,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),6,2,7,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFlexUnary(TestTags::sweep(),6,2,7,0,ipba.ipl()); + (void) new OptFlexUnary(TestTags::sweep(),6,2,7,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFixPUnary(TestTag::sweep,p30,0,ipba.ipl()); - (void) new ManFixPUnary(TestTag::sweep,p30,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFixPUnary(TestTag::sweep,p30,0,ipba.ipl()); - (void) new OptFixPUnary(TestTag::sweep,p30,Gecode::Int::Limits::min,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,8,0,9,0,ipba.ipl()); - (void) new ManFlexUnary(TestTag::sweep,8,0,9,Gecode::Int::Limits::min,ipba.ipl()); - (void) new OptFlexUnary(TestTag::sweep,8,0,9,0,ipba.ipl()); - (void) new OptFlexUnary(TestTag::sweep,8,0,9,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFixPUnary(TestTags::sweep(),p30,0,ipba.ipl()); + (void) new ManFixPUnary(TestTags::sweep(),p30,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFixPUnary(TestTags::sweep(),p30,0,ipba.ipl()); + (void) new OptFixPUnary(TestTags::sweep(),p30,Gecode::Int::Limits::min,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),8,0,9,0,ipba.ipl()); + (void) new ManFlexUnary(TestTags::sweep(),8,0,9,Gecode::Int::Limits::min,ipba.ipl()); + (void) new OptFlexUnary(TestTags::sweep(),8,0,9,0,ipba.ipl()); + (void) new OptFlexUnary(TestTags::sweep(),8,0,9,Gecode::Int::Limits::min,ipba.ipl()); } } }; diff --git a/test/nogoods.cpp b/test/nogoods.cpp index 80baab57ab..2e819fd5f2 100644 --- a/test/nogoods.cpp +++ b/test/nogoods.cpp @@ -275,7 +275,7 @@ namespace Test { bool n = false; do { for (unsigned int t = 1; t<=4; t++) { - TestTags queens(TestTag::normal,TestTag::check); + TestTags queens = TestTags::check(); (void) new NoGoods(queens,INT_VAL_MIN(),t,a,n); (void) new NoGoods(queens,INT_VAL_MAX(),t,a,n); (void) new NoGoods(queens,INT_VAL_SPLIT_MIN(),t,a,n); @@ -283,10 +283,10 @@ namespace Test { (void) new NoGoods(queens,INT_VALUES_MIN(),t,a,n); (void) new NoGoods(queens,INT_VALUES_MAX(),t,a,n); #ifdef GECODE_HAS_SET_VARS - (void) new NoGoods(TestTag::normal,SET_VAL_MIN_INC(),t,a,n); - (void) new NoGoods(TestTag::normal,SET_VAL_MIN_EXC(),t,a,n); - (void) new NoGoods(TestTag::normal,SET_VAL_MAX_INC(),t,a,n); - (void) new NoGoods(TestTag::normal,SET_VAL_MAX_EXC(),t,a,n); + (void) new NoGoods(TestTags::standard(),SET_VAL_MIN_INC(),t,a,n); + (void) new NoGoods(TestTags::standard(),SET_VAL_MIN_EXC(),t,a,n); + (void) new NoGoods(TestTags::standard(),SET_VAL_MAX_INC(),t,a,n); + (void) new NoGoods(TestTags::standard(),SET_VAL_MAX_EXC(),t,a,n); #endif } n = !n; diff --git a/test/public-runner-smoke.cpp b/test/public-runner-smoke.cpp index ae09f3164d..712dcbc887 100644 --- a/test/public-runner-smoke.cpp +++ b/test/public-runner-smoke.cpp @@ -59,7 +59,7 @@ namespace { class FailingSmokeTest : public Test::Base { public: FailingSmokeTest(void) - : Test::Base("Smoke::B-Fail", Test::TestTag::sweep) {} + : Test::Base("Smoke::B-Fail", Test::TestTags::sweep()) {} bool run(void) override { failing_runs++; @@ -141,8 +141,8 @@ main(void) { "-list-with-tags should succeed")) { return EXIT_FAILURE; } - if (!require(tagged_list_output.find(pass_name + " [normal]") != std::string::npos, - "default test should have the normal tag")) { + if (!require(tagged_list_output.find(pass_name + " [standard]") != std::string::npos, + "default test should have the standard tag")) { return EXIT_FAILURE; } if (!require(tagged_list_output.find("Smoke::B-Fail [sweep]") != std::string::npos, @@ -151,19 +151,19 @@ main(void) { } std::string normal_output; - if (!require(run_and_capture({"public-runner-smoke", "-tag", "normal", + if (!require(run_and_capture({"public-runner-smoke", "-tag", "standard", "-iter", "1", "-stop", "true"}, normal_output) == EXIT_SUCCESS, - "normal tag selection should succeed")) { + "standard tag selection should succeed")) { return EXIT_FAILURE; } if (!require(normal_output.find(pass_name) != std::string::npos && normal_output.find(fail_name) == std::string::npos, - "normal tag selection chose the wrong tests")) { + "standard tag selection chose the wrong tests")) { return EXIT_FAILURE; } if (!require(passing_runs == 1 && failing_runs == 0, - "normal tag selection run counts are wrong")) { + "standard tag selection run counts are wrong")) { return EXIT_FAILURE; } @@ -230,7 +230,7 @@ main(void) { return EXIT_FAILURE; std::string combined_output; - if (!require(run_and_capture({"public-runner-smoke", "-tag", "normal", + if (!require(run_and_capture({"public-runner-smoke", "-tag", "standard", "-tag", "sweep", "-iter", "1", "-stop", "true"}, combined_output) == EXIT_FAILURE, "multiple tags should select their union")) { diff --git a/test/search.cpp b/test/search.cpp index d3ecaed43b..70cf9d8cc0 100644 --- a/test/search.cpp +++ b/test/search.cpp @@ -395,7 +395,7 @@ namespace Test { Test(const std::string& s, HowToBranch _htb1, HowToBranch _htb2, HowToBranch _htb3, HowToConstrain _htc=HTC_NONE) - : Test(TestTag::normal,s,_htb1,_htb2,_htb3,_htc) {} + : Test(TestTags::standard(),s,_htb1,_htb2,_htb3,_htc) {} }; /// Randomly resize a live leaf engine from another thread @@ -495,7 +495,7 @@ namespace Test { return caught && (live == (clone ? 1 : 0)); } public: - PBSConstructionFailure(void) : Base("Search::PBS::ConstructionFailure", TestTags(TestTag::normal,TestTag::check)) {} + PBSConstructionFailure(void) : Base("Search::PBS::ConstructionFailure", TestTags::check()) {} bool run(void) override { for (unsigned int threads : {1U,4U}) for (bool clone : {false,true}) @@ -586,7 +586,7 @@ namespace Test { } public: WorkerControlSequentialPause(void) - : Base("Search::WorkerControl::SequentialPause", TestTags(TestTag::normal,TestTag::check)) {} + : Base("Search::WorkerControl::SequentialPause", TestTags::check()) {} bool run(void) override { #ifdef GECODE_HAS_THREADS return check(0U) && check(1U) && @@ -613,7 +613,7 @@ namespace Test { return false; } public: - WorkerControlAPI(void) : Base("Search::WorkerControl::API", TestTags(TestTag::normal,TestTag::check)) {} + WorkerControlAPI(void) : Base("Search::WorkerControl::API", TestTags::check()) {} bool run(void) override { using Gecode::Search::WorkerControl; WorkerControl empty; @@ -685,7 +685,7 @@ namespace Test { class WorkerControlPBSPause : public Base { public: WorkerControlPBSPause(void) - : Base("Search::WorkerControl::PBS::Pause", TestTags(TestTag::normal,TestTag::check)) {} + : Base("Search::WorkerControl::PBS::Pause", TestTags::check()) {} bool run(void) override { bool ok = true; // A sequential portfolio must reject assets that could block its round. @@ -1165,16 +1165,16 @@ namespace Test { (htb2.htb() == HTB_NARY) && (htb3.htb() == HTB_BINARY) && (c_d == 1) && (a_d == 1) && (t == 1) - ? TestTags(TestTag::normal,TestTag::check) - : TestTags(TestTag::sweep), + ? TestTags::check() + : TestTags(TestTags::sweep()), htb1.htb(),htb2.htb(),htb3.htb(),c_d,a_d,t); - new DFS(TestTag::normal, + new DFS(TestTags::standard(), HTB_NONE, HTB_NONE, HTB_NONE, c_d, a_d, t); - new DFS(TestTag::sweep, + new DFS(TestTags::sweep(), HTB_NONE, HTB_NONE, HTB_NONE, c_d, a_d, t); - new DFS(TestTag::sweep, + new DFS(TestTags::sweep(), HTB_NONE, HTB_NONE, HTB_NONE, c_d, a_d, t); } @@ -1204,19 +1204,19 @@ namespace Test { (htb2.htb() == HTB_BINARY) && (htb3.htb() == HTB_BINARY) && (c_d == 1) && (a_d == 1) && (t == 1) - ? TestTags(TestTag::normal) - : TestTags(TestTag::sweep), + ? TestTags(TestTags::standard()) + : TestTags(TestTags::sweep()), htc.htc(),htb1.htb(),htb2.htb(),htb3.htb(), c_d,a_d,t); } (void) new BAB - (TestTag::normal,HTC_NONE,HTB_NONE,HTB_NONE,HTB_NONE, + (TestTags::standard(),HTC_NONE,HTB_NONE,HTB_NONE,HTB_NONE, c_d,a_d,t); (void) new BAB - (TestTag::sweep,HTC_NONE,HTB_NONE,HTB_NONE,HTB_NONE, + (TestTags::sweep(),HTC_NONE,HTB_NONE,HTB_NONE,HTB_NONE, c_d,a_d,t); (void) new BAB - (TestTag::sweep,HTC_NONE,HTB_NONE,HTB_NONE,HTB_NONE, + (TestTags::sweep(),HTC_NONE,HTB_NONE,HTB_NONE,HTB_NONE, c_d,a_d,t); } // Restart-based search diff --git a/test/set.hh b/test/set.hh index 01cb0907ff..f6fb667359 100644 --- a/test/set.hh +++ b/test/set.hh @@ -311,7 +311,7 @@ namespace Test { */ SetTest(const std::string& s, int a, const Gecode::IntSet& d, bool r=false, int w=0) - : SetTest(TestTag::normal,s,a,d,r,w) {} + : SetTest(TestTags::standard(),s,a,d,r,w) {} /// Construct and register a test with explicitly assigned tags SetTest(TestTags tags, const std::string& s, int a, const Gecode::IntSet& d, bool r=false, int w=0) diff --git a/test/set/channel.cpp b/test/set/channel.cpp index 1ea3f0ed4c..26269a4c81 100644 --- a/test/set/channel.cpp +++ b/test/set/channel.cpp @@ -63,7 +63,7 @@ namespace Test { namespace Set { public: /// Create and register test ChannelSorted(const char* t) - : SetTest(TestTag::sweep,t,1,ds_33,false,3) {} + : SetTest(TestTags::sweep(),t,1,ds_33,false,3) {} /// %Test whether \a x is solution virtual bool solution(const SetAssignment& x) const { if (x.ints()[0]>=x.ints()[1] || @@ -103,7 +103,7 @@ namespace Test { namespace Set { public: /// Create and register test ChannelInt(const char* t, const IntSet& d, int _ssize, int _isize) - : SetTest(TestTag::sweep,t,_ssize,d,false,_isize), ssize(_ssize), isize(_isize) {} + : SetTest(TestTags::sweep(),t,_ssize,d,false,_isize), ssize(_ssize), isize(_isize) {} /// %Test whether \a x is solution virtual bool solution(const SetAssignment& x) const { for (int i=0; i 2) @@ -319,7 +319,7 @@ namespace Test { namespace Set { public: /// Create and register test ElementSetConst(const char* t) - : SetTest(TestTag::sweep,t,1,ds_13,false,true), i0(-3,-3), i1(-1,1), i2(0,2) {} + : SetTest(TestTags::sweep(),t,1,ds_13,false,true), i0(-3,-3), i1(-1,1), i2(0,2) {} /// %Test whether \a x is solution virtual bool solution(const SetAssignment& x) const { if (x.intval() < 0 || x.intval() > 2) @@ -346,7 +346,7 @@ namespace Test { namespace Set { public: /// Create and register test MatrixIntSet(void) - : SetTest(TestTag::sweep,"Element::Matrix::IntSet",1,IntSet(0,3),false,2), + : SetTest(TestTags::sweep(),"Element::Matrix::IntSet",1,IntSet(0,3),false,2), tm(4) { tm[0]=IntSet(0,0); tm[1]=IntSet(1,1); tm[2]=IntSet(2,2); tm[3]=IntSet(3,3); diff --git a/test/set/exec.cpp b/test/set/exec.cpp index a411565828..8a4e4c2726 100644 --- a/test/set/exec.cpp +++ b/test/set/exec.cpp @@ -51,7 +51,7 @@ namespace Test { namespace Set { public: /// Create and register test Wait(int n, bool sf0) - : SetTest(TestTags(TestTag::normal,TestTag::check), + : SetTest(TestTags::check(), "Wait::"+str(n)+"::"+ (sf0 ? "std::function" : "funptr"),n, Gecode::IntSet(0,n),false), sf(sf0) {} diff --git a/test/set/mm-set.cpp b/test/set/mm-set.cpp index 49c5e4a7ff..274f62c170 100755 --- a/test/set/mm-set.cpp +++ b/test/set/mm-set.cpp @@ -4506,17 +4506,17 @@ namespace Test { namespace Int { s = "0" + s; } TestTags eq_zero_tags = i == 0 - ? TestTags(TestTag::normal) : TestTags(TestTag::sweep); + ? TestTags(TestTags::standard()) : TestTags(TestTags::sweep()); (void) new SetExprConst(eq_zero_tags,si[i],s,Gecode::SRT_EQ,0); - (void) new SetExprConst(TestTag::sweep,si[i],s,Gecode::SRT_EQ,1); - (void) new SetExprConst(TestTag::sweep,si[i],s,Gecode::SRT_NQ,0); - (void) new SetExprConst(TestTag::sweep,si[i],s,Gecode::SRT_NQ,1); - (void) new SetExprConst(TestTag::sweep,si[i],s,Gecode::SRT_SUB,0); - (void) new SetExprConst(TestTag::sweep,si[i],s,Gecode::SRT_SUB,1); - (void) new SetExprConst(TestTag::sweep,si[i],s,Gecode::SRT_SUP,0); - (void) new SetExprConst(TestTag::sweep,si[i],s,Gecode::SRT_SUP,1); - (void) new SetExprConst(TestTag::sweep,si[i],s,Gecode::SRT_DISJ,0); - (void) new SetExprConst(TestTag::sweep,si[i],s,Gecode::SRT_DISJ,1); + (void) new SetExprConst(TestTags::sweep(),si[i],s,Gecode::SRT_EQ,1); + (void) new SetExprConst(TestTags::sweep(),si[i],s,Gecode::SRT_NQ,0); + (void) new SetExprConst(TestTags::sweep(),si[i],s,Gecode::SRT_NQ,1); + (void) new SetExprConst(TestTags::sweep(),si[i],s,Gecode::SRT_SUB,0); + (void) new SetExprConst(TestTags::sweep(),si[i],s,Gecode::SRT_SUB,1); + (void) new SetExprConst(TestTags::sweep(),si[i],s,Gecode::SRT_SUP,0); + (void) new SetExprConst(TestTags::sweep(),si[i],s,Gecode::SRT_SUP,1); + (void) new SetExprConst(TestTags::sweep(),si[i],s,Gecode::SRT_DISJ,0); + (void) new SetExprConst(TestTags::sweep(),si[i],s,Gecode::SRT_DISJ,1); if ( (i % 31) == 0) { @@ -4530,16 +4530,16 @@ namespace Test { namespace Int { } ss=s+"::"+ss; TestTags eq_tags = (i == 0) && (j == 0) - ? TestTags(TestTag::normal) : TestTags(TestTag::sweep); + ? TestTags(TestTags::standard()) : TestTags(TestTags::sweep()); (void) new SetExprExpr(eq_tags,si[i],si[j],ss, Gecode::SRT_EQ); - (void) new SetExprExpr(TestTag::sweep,si[i],si[j],ss, + (void) new SetExprExpr(TestTags::sweep(),si[i],si[j],ss, Gecode::SRT_NQ); - (void) new SetExprExpr(TestTag::sweep,si[i],si[j],ss, + (void) new SetExprExpr(TestTags::sweep(),si[i],si[j],ss, Gecode::SRT_SUB); - (void) new SetExprExpr(TestTag::sweep,si[i],si[j],ss, + (void) new SetExprExpr(TestTags::sweep(),si[i],si[j],ss, Gecode::SRT_SUP); - (void) new SetExprExpr(TestTag::sweep,si[i],si[j],ss, + (void) new SetExprExpr(TestTags::sweep(),si[i],si[j],ss, Gecode::SRT_DISJ); } } diff --git a/test/set/precede.cpp b/test/set/precede.cpp index 74c2d498bc..e2c00ac375 100755 --- a/test/set/precede.cpp +++ b/test/set/precede.cpp @@ -64,7 +64,7 @@ namespace Test { namespace Set { public: /// Create and register test Single(int s0, int t0) - : SetTest(TestTag::sweep,"Precede::Single::"+str(s0)+"<"+str(t0),4,ds,false), + : SetTest(TestTags::sweep(),"Precede::Single::"+str(s0)+"<"+str(t0),4,ds,false), s(s0), t(t0) {} /// %Test whether \a x is solution virtual bool solution(const SetAssignment& x) const { @@ -121,9 +121,9 @@ namespace Test { namespace Set { Single _a(2, 3); Single _b(0, 3); - Multi _c(TestTag::normal,Gecode::IntArgs({1,2,3})); - Multi _d(TestTag::sweep,Gecode::IntArgs({3,2,1})); - Multi _e(TestTag::sweep,Gecode::IntArgs({4,2,3,1})); + Multi _c(TestTags::standard(),Gecode::IntArgs({1,2,3})); + Multi _d(TestTags::sweep(),Gecode::IntArgs({3,2,1})); + Multi _e(TestTags::sweep(),Gecode::IntArgs({4,2,3,1})); } diff --git a/test/set/rel-op-const.cpp b/test/set/rel-op-const.cpp index b2188371aa..27a30df272 100755 --- a/test/set/rel-op-const.cpp +++ b/test/set/rel-op-const.cpp @@ -87,7 +87,7 @@ namespace Test { namespace Set { /// Create and register test RelSIS(Gecode::SetOpType sot0, Gecode::SetRelType srt0, int intSet, bool inverse0) - : SetTest(TestTag::sweep,"RelOp::ConstSIS::"+str(sot0)+"::"+str(srt0)+"::"+ + : SetTest(TestTags::sweep(),"RelOp::ConstSIS::"+str(sot0)+"::"+str(srt0)+"::"+ str(intSet)+(inverse0 ? "i" :""),2,ds_22,false) , is(iss[intSet]), sot(sot0), srt(srt0), inverse(inverse0) {} /// %Test whether \a x is solution @@ -185,8 +185,8 @@ namespace Test { namespace Set { RelSSI(Gecode::SetOpType sot0, Gecode::SetRelType srt0, int intSet) : SetTest(sot0 == Gecode::SOT_UNION - ? TestTags(TestTag::normal,TestTag::check) - : TestTags(TestTag::sweep), + ? TestTags::check() + : TestTags(TestTags::sweep()), "RelOp::ConstSSI::"+str(sot0)+"::"+str(srt0)+"::"+ str(intSet),2,ds_22,false) , is(iss[intSet]), sot(sot0), srt(srt0) {} @@ -279,7 +279,7 @@ namespace Test { namespace Set { : SetTest((sot0 == Gecode::SOT_DUNION) && (srt0 == Gecode::SRT_CMPL) && (intSet0 == 0) && (intSet1 == 0) - ? TestTag::normal : TestTag::sweep, + ? TestTags::standard() : TestTags::sweep(), "RelOp::ConstISI::"+str(sot0)+"::"+str(srt0)+"::"+ str(intSet0)+"::"+str(intSet1)+ (inverse0 ? "i" : ""),1,ds_33,false) diff --git a/test/set/rel-op.cpp b/test/set/rel-op.cpp index 80aaad6f7a..a70ac038b4 100755 --- a/test/set/rel-op.cpp +++ b/test/set/rel-op.cpp @@ -82,7 +82,7 @@ namespace Test { namespace Set { public: /// Create and register test Rel(Gecode::SetOpType sot0, Gecode::SetRelType srt0, int share0=0) - : SetTest(TestTag::sweep,"RelOp::"+str(sot0)+"::"+str(srt0)+"::S"+str(share0), + : SetTest(TestTags::sweep(),"RelOp::"+str(sot0)+"::"+str(srt0)+"::S"+str(share0), share0 == 0 ? 3 : 2,ds_22,false) , sot(sot0), srt(srt0), share(share0) {} /// %Test whether \a x is solution @@ -179,7 +179,7 @@ namespace Test { namespace Set { public: /// Create and register test RelN(Gecode::SetOpType sot0, int n0, int shared0, bool withConst0) - : SetTest(TestTag::sweep,"RelOp::N::"+str(sot0)+"::"+str(n0)+"::S"+str(shared0)+ + : SetTest(TestTags::sweep(),"RelOp::N::"+str(sot0)+"::"+str(n0)+"::S"+str(shared0)+ "::C"+str(withConst0 ? 1 : 0), shared0 == 0 ? n0+1 : (shared0 <= 2 ? 3 : 2),ds_12,false) , sot(sot0), n(n0), shared(shared0), withConst(withConst0) @@ -366,7 +366,7 @@ namespace Test { namespace Set { public: /// Create and register test RelIntN(Gecode::SetOpType sot0, int n0, bool withConst0) - : SetTest(TestTag::sweep,"RelOp::IntN::"+str(sot0)+"::"+str(n0)+ + : SetTest(TestTags::sweep(),"RelOp::IntN::"+str(sot0)+"::"+str(n0)+ "::C"+str(withConst0 ? 1 : 0), 1,ds_12,false,n0) , sot(sot0), n(n0), withConst(withConst0) diff --git a/test/set/rel.cpp b/test/set/rel.cpp index e408cc8b8f..1de93483c8 100644 --- a/test/set/rel.cpp +++ b/test/set/rel.cpp @@ -60,7 +60,7 @@ namespace Test { namespace Set { /// Create and register test RelBin(Gecode::SetRelType srt0, bool shared0) : SetTest((srt0 == Gecode::SRT_CMPL) && !shared0 - ? TestTag::normal : TestTag::sweep, + ? TestTags::standard() : TestTags::sweep(), "Rel::Bin::"+str(srt0)+"::S"+(shared0 ? "1":"0"), shared0 ? 1 : 2,ds_33,true) , srt(srt0), shared(shared0){} diff --git a/test/set/sequence.cpp b/test/set/sequence.cpp index bf6ecf9bde..2e32cc06c3 100644 --- a/test/set/sequence.cpp +++ b/test/set/sequence.cpp @@ -83,8 +83,8 @@ namespace Test { namespace Set { public: /// Create and register test SeqU(int n0) - : SetTest(n0 == 1 ? TestTags(TestTag::normal,TestTag::check) - : TestTags(TestTag::normal), + : SetTest(n0 == 1 ? TestTags::check() + : TestTags(TestTags::standard()), "Sequence::SeqU"+str(n0),n0+1,ds_33,false), n(n0) {} /// %Test whether \a x is solution virtual bool solution(const SetAssignment& x) const { diff --git a/test/test.cpp b/test/test.cpp index 0ce1b5a68a..2153d39b5d 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -62,7 +62,7 @@ namespace Test { /// Tags supported by the test runner static const TestTagDescription test_tag_descriptions[] = { {"check", TestTag::check}, - {"normal", TestTag::normal}, + {"standard", TestTag::standard}, {"sweep", TestTag::sweep} }; @@ -123,7 +123,7 @@ namespace Test { * */ Base::Base(std::string s) - : Base(s, TestTag::normal) {} + : Base(s, TestTags::standard()) {} Base::Base(std::string s, TestTags t) : _name(std::move(s)), _tags(t), _next(_tests), _rand(Gecode::Support::RandomGenerator()) { diff --git a/test/test.hh b/test/test.hh index 21369afad0..32d1a67149 100755 --- a/test/test.hh +++ b/test/test.hh @@ -97,7 +97,7 @@ namespace Test { /// Tags for test selection enum class TestTag : unsigned int { check = 1U << 0, ///< Basic integrity tests - normal = 1U << 1, ///< Normal test suite + standard = 1U << 1, ///< Standard test suite sweep = 1U << 2 ///< Really heavy sweep tests }; @@ -113,6 +113,12 @@ namespace Test { TestTags(TestTag t); /// Initialize with tags \a t0 and \a t1 TestTags(TestTag t0, TestTag t1); + /// Integrity tests, also part of the standard suite + static TestTags check(void); + /// Standard suite without expensive sweeps + static TestTags standard(void); + /// Expensive parameter sweeps + static TestTags sweep(void); /// Return set with all known tags static TestTags all(void); /// Whether no tags are set @@ -190,7 +196,7 @@ namespace Test { /// How many tests static unsigned int _n_tests; public: - /// Create and register a normal test with name \a s + /// Create and register a standard test with name \a s Base(std::string s); /** \brief Create and register test with name \a s and tags \a t * diff --git a/test/test.hpp b/test/test.hpp index 9ef24cc0f0..7681468118 100755 --- a/test/test.hpp +++ b/test/test.hpp @@ -47,6 +47,18 @@ namespace Test { TestTags::TestTags(TestTag t0, TestTag t1) : _mask(static_cast(t0) | static_cast(t1)) {} + inline TestTags + TestTags::check(void) { + return TestTags(TestTag::standard,TestTag::check); + } + inline TestTags + TestTags::standard(void) { + return TestTags(TestTag::standard); + } + inline TestTags + TestTags::sweep(void) { + return TestTags(TestTag::sweep); + } inline bool TestTags::empty(void) const { return _mask == 0; From 3b602590ccd9b1f278fd43fadfd488442d7a5471 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Mon, 5 Oct 2026 06:09:08 +0200 Subject: [PATCH 18/23] Add minimum-distance constraints with single and decomposed propagation --- Makefile.in | 6 +- changelog.in | 13 + cmake/GecodeSources.cmake | 2 + gecode/int.hh | 116 +++++++ gecode/int/min-distance.cpp | 617 ++++++++++++++++++++++++++++++++++++ gecode/int/min-distance.hpp | 62 ++++ test/int/min-distance.cpp | 277 ++++++++++++++++ 7 files changed, 1090 insertions(+), 3 deletions(-) create mode 100644 gecode/int/min-distance.cpp create mode 100644 gecode/int/min-distance.hpp create mode 100644 test/int/min-distance.cpp diff --git a/Makefile.in b/Makefile.in index 62bd48f92c..60334f8678 100755 --- a/Makefile.in +++ b/Makefile.in @@ -338,7 +338,7 @@ INTSRC0 = \ order.cpp order/propagate.cpp \ unary.cpp cumulative.cpp cumulatives.cpp \ circuit.cpp no-overlap.cpp nvalues.cpp \ - member.cpp branch/action.cpp branch/chb.cpp \ + member.cpp min-distance.cpp branch/action.cpp branch/chb.cpp \ arithmetic/mult.cpp \ branch/view-sel.cpp branch/val-sel-commit.cpp \ branch/view-values.cpp \ @@ -398,7 +398,7 @@ INTHDR0 = \ view/offset.hpp view/rel-test.hpp view/scale.hpp view/iter.hpp \ arithmetic.hh array.hpp array-traits.hpp bool.hh branch.hh \ distinct.hh dom.hh \ - element.hh exception.hpp gcc.hh linear.hh \ + element.hh min-distance.hpp exception.hpp gcc.hh linear.hh \ reify.hpp propagator.hpp extensional.hh rel.hh \ sorted.hh var-imp.hpp view.hpp ipl.hpp irt.hpp \ channel.hh channel.hpp channel/dom.hpp channel/val.hpp \ @@ -1121,7 +1121,7 @@ INTTESTSRC00 = \ rel linear gcc sorted unshare exec sequence \ mm-arithmetic mm-bool mm-lin mm-count mm-rel \ bin-packing order unary cumulative cumulatives circuit \ - no-overlap precede nvalues member + no-overlap precede nvalues member min-distance INTTESTSRC0 = test/int.cpp $(INTTESTSRC00:%=test/int/%.cpp) INTTESTOBJ = $(INTTESTSRC0:%.cpp=%$(OBJSUFFIX)) diff --git a/changelog.in b/changelog.in index f66ceaa446..219972aeb1 100755 --- a/changelog.in +++ b/changelog.in @@ -149,6 +149,19 @@ to register and run Gecode-style tests for every configured variable family. Support shared and static harness libraries using the configured Gecode library variants. Add exact replay of a failed test iteration with `-replay`. +[ENTRY] +Module: int +What: new +Rank: major +[DESCRIPTION] +Add exact minimum-distance constraints over indexed sites, with decomposed +and single-propagator forward-bound propagation, optional conflict-matching +upper bounds, and inclusive requirements for selected-position pairs. +Distances can use a shared matrix or a shared callable evaluated on demand. +The propagation algorithms follow: +M. Z. Lagerkvist, Propagation Algorithms for the Minimum-Distance Constraint +over Selected Points, ModRef 2026. + [RELEASE] Version: 6.4.0 Date: 2026-07-15 diff --git a/cmake/GecodeSources.cmake b/cmake/GecodeSources.cmake index eb013c2682..09b4365587 100644 --- a/cmake/GecodeSources.cmake +++ b/cmake/GecodeSources.cmake @@ -96,6 +96,7 @@ set(GECODE_INT_SOURCES gecode/int/linear/bool-post.cpp gecode/int/linear/int-post.cpp gecode/int/member.cpp + gecode/int/min-distance.cpp gecode/int/no-overlap.cpp gecode/int/nvalues.cpp gecode/int/order.cpp @@ -416,6 +417,7 @@ set(GECODE_TEST_SOURCES test/int/gcc.cpp test/int/linear.cpp test/int/member.cpp + test/int/min-distance.cpp test/int/mm-arithmetic.cpp test/int/mm-bool.cpp test/int/mm-count.cpp diff --git a/gecode/int.hh b/gecode/int.hh index 9166211d6d..7d0e765955 100755 --- a/gecode/int.hh +++ b/gecode/int.hh @@ -2898,6 +2898,122 @@ namespace Gecode { #include +namespace Gecode { + + + /** + * \defgroup TaskModelIntMinDistance Minimum distance constraints + * \ingroup TaskModelInt + */ + //@{ + /** \brief Shared distances between indexed sites + * + * Distances are nonnegative, symmetric, and zero on the diagonal. + * No triangle inequality is required. Site indices range from zero to + * size()-1. Matrix entries or a callable are shared across propagators, + * clones, and search threads. + */ + class IntDistance : public SharedHandle { + protected: + /// Shared matrix or callable + class Data : public SharedHandle::Object { + public: + const int n; ///< Number of sites + const IntSharedArray matrix; ///< Row-major matrix, empty for a callable + const std::function function; ///< Computed distance + Data(int n, const IntArgs& matrix); + Data(int n, std::function function); + virtual ~Data(void); + }; + public: + /** \brief Copy and validate an \a n by \a n row-major distance matrix + * + * Throws Int::OutOfLimits for invalid sizes or distances, + * Int::ArgumentSizeMismatch for a wrong number of entries, and + * Int::IllegalOperation for asymmetry or a nonzero diagonal. + */ + GECODE_INT_EXPORT IntDistance(int n, const IntArgs& matrix); + /** \brief Compute distances on demand for \a n sites + * + * The callable must return a stable, symmetric, nonnegative distance + * within Int::Limits, and zero for equal indices. It must own or share + * its captured data, be safe for concurrent calls, and not depend on a + * Space. Construction does not evaluate it or materialize a matrix. + * Results are checked for range and a zero diagonal when evaluated; + * symmetry is the caller's responsibility. + * Throws Int::OutOfLimits for an invalid site count and InvalidFunction + * for an empty callable. + */ + GECODE_INT_EXPORT IntDistance(int n, std::function function); + /// Number of sites + int size(void) const; + /// Distance between valid indices \a a and \a b + int operator ()(int a, int b) const; + }; + + /// Organization of forward-bound minimum-distance propagation + enum class MinDistancePropKind { + MDP_DECOMPOSED, ///< One propagator per selected-position pair + MDP_SINGLE ///< One propagator with advisors and cached pair maxima + }; + /// One propagator per selected-position pair + static constexpr MinDistancePropKind MDP_DECOMPOSED = + MinDistancePropKind::MDP_DECOMPOSED; + /// One propagator with advisors and cached pair maxima + static constexpr MinDistancePropKind MDP_SINGLE = + MinDistancePropKind::MDP_SINGLE; + + /** \brief Post \f$z=\min_{i + namespace Gecode { /** diff --git a/gecode/int/min-distance.cpp b/gecode/int/min-distance.cpp new file mode 100644 index 0000000000..f8a1f34d91 --- /dev/null +++ b/gecode/int/min-distance.cpp @@ -0,0 +1,617 @@ +/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ +/* + * Main authors: + * Mikael Zayenz Lagerkvist + * + * Copyright: + * Mikael Zayenz Lagerkvist, 2026 + * + * This file is part of Gecode, the generic constraint + * development environment: + * http://www.gecode.dev + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + +#include + +#include +#include + +namespace Gecode { + + IntDistance::Data::Data(int n0, const IntArgs& m) + : n(n0), matrix(m) {} + + IntDistance::Data::Data(int n0, std::function f) + : n(n0), function(std::move(f)) {} + + IntDistance::Data::~Data(void) {} + + IntDistance::IntDistance(int n, const IntArgs& matrix) { + Int::Limits::positive(n,"IntDistance"); + if (static_cast(n)*n != matrix.size()) + throw Int::ArgumentSizeMismatch("IntDistance"); + for (int a=0; a f) { + Int::Limits::positive(n,"IntDistance"); + if (!f) + throw InvalidFunction("IntDistance"); + object(new Data(n,std::move(f))); + } + +} + +/** + * \namespace Gecode::Int::MinDistance + * + * The forward-bound and greedy conflict-matching algorithms follow: + * M. Z. Lagerkvist, Propagation Algorithms for the Minimum-Distance + * Constraint over Selected Points, ModRef 2026. + * https://github.com/zayenz/modref2026-minimum-distance-propagators + * + * \brief Minimum-distance propagators over indexed sites + */ +namespace Gecode { namespace Int { namespace MinDistance { + + /// Inclusive requirement, with an empty matrix denoting all zeroes + forceinline int + requirement(const IntSharedArray& r, int n, int i, int j) { + return !r ? 0 : r[i*n+j]; + } + + /// Prune the partner of an assigned endpoint + ExecStatus + forward(Space& home, IntView a, IntView b, int threshold, + const IntDistance& d, bool& changed) { + Region region; + int* remove = region.alloc(b.size()); + int nr = 0; + for (ViewValues v(b); v(); ++v) + if (d(a.val(),v.val()) < threshold) + remove[nr++] = v.val(); + if (nr != 0) { + Iter::Values::Array values(remove,static_cast(nr)); + ModEvent me = b.minus_v(home,values,false); + GECODE_ME_CHECK(me); + changed |= me_modified(me); + } + return ES_OK; + } + + /// Pair maximum and its witness + struct PairCache { + int a, b, upper; + }; + + /// Recompute the maximum distance between current domains + void + pair_max(IntView x, IntView y, const IntDistance& d, PairCache& c) { + c.upper = -1; + for (ViewValues a(x); a(); ++a) + for (ViewValues b(y); b(); ++b) { + int v = d(a.val(),b.val()); + if (v > c.upper) { + c.a = a.val(); c.b = b.val(); c.upper = v; + } + } + } + + /// Validate and bind a complete assignment + ExecStatus + assigned(Space& home, const ViewArray& x, IntView z, + const IntDistance& d, const IntSharedArray& r) { + int minimum = Limits::max; + for (int i=0; i& x, const IntDistance& d, + const IntSharedArray& r, bool& changed, bool& realized) { + int count = 0, first = -1, second = -1; + for (int i=0; i a(x[i]); a() && !supported; ++a) + for (ViewValues b(x[j]); b(); ++b) + if (d(a.val(),b.val()) == 0) { + supported = true; + break; + } + if (supported) { + first = i; second = j; count++; + } + } + if (count == 0) + return ES_FAILED; + if (count == 1) { + // Only this pair can attain zero, so both endpoints need zero support. + Region region; + for (int pass=0; pass<2; pass++) { + IntView a = x[pass == 0 ? first : second]; + IntView b = x[pass == 0 ? second : first]; + int* remove = region.alloc(a.size()); + int nr = 0; + for (ViewValues v(a); v(); ++v) { + bool supported = false; + for (ViewValues w(b); w(); ++w) + if (d(v.val(),w.val()) == 0) { + supported = true; + break; + } + if (!supported) + remove[nr++] = v.val(); + } + if (nr != 0) { + Iter::Values::Array values(remove,static_cast(nr)); + ModEvent me = a.minus_v(home,values,false); + GECODE_ME_CHECK(me); + changed |= me_modified(me); + } + } + } + return ES_OK; + } + + /// Forward-bound actor for one selected-position pair + class Pair : public Propagator { + protected: + IntView x, y, z; + IntDistance d; + int r; + Pair(Home home, IntView x0, IntView y0, IntView z0, + const IntDistance& d0, int r0) + : Propagator(home), x(x0), y(y0), z(z0), d(d0), r(r0) { + home.notice(*this,AP_DISPOSE); + x.subscribe(home,*this,PC_INT_DOM); + y.subscribe(home,*this,PC_INT_DOM); + z.subscribe(home,*this,PC_INT_BND); + } + Pair(Space& home, Pair& p) + : Propagator(home,p), d(p.d), r(p.r) { + x.update(home,p.x); y.update(home,p.y); z.update(home,p.z); + } + public: + static ExecStatus post(Home home, IntView x, IntView y, IntView z, + const IntDistance& d, int r) { + if (x.assigned() && y.assigned()) { + int v = d(x.val(),y.val()); + if (v < r) + return ES_FAILED; + GECODE_ME_CHECK(z.lq(home,v)); + } else { + (void) new (home) Pair(home,x,y,z,d,r); + } + return ES_OK; + } + virtual Actor* copy(Space& home) { + return new (home) Pair(home,*this); + } + virtual PropCost cost(const Space&, const ModEventDelta&) const { + return PropCost::quadratic(PropCost::HI,d.size()); + } + virtual void reschedule(Space& home) { + x.reschedule(home,*this,PC_INT_DOM); + y.reschedule(home,*this,PC_INT_DOM); + z.reschedule(home,*this,PC_INT_BND); + } + virtual ExecStatus propagate(Space& home, const ModEventDelta&) { + int threshold = std::max(r,z.min()); + if (x.assigned() && y.assigned()) { + int v = d(x.val(),y.val()); + if (v < threshold) + return ES_FAILED; + GECODE_ME_CHECK(z.lq(home,v)); + return home.ES_SUBSUMED(*this); + } + bool changed = false; + if (x.assigned()) { + GECODE_ES_CHECK(forward(home,x,y,threshold,d,changed)); + } else if (y.assigned()) { + GECODE_ES_CHECK(forward(home,y,x,threshold,d,changed)); + } + PairCache c; + pair_max(x,y,d,c); + if (c.upper < threshold) + return ES_FAILED; + ModEvent me = z.lq(home,c.upper); + GECODE_ME_CHECK(me); + return (changed || me_modified(me) || (z.min() > threshold)) ? ES_NOFIX : ES_FIX; + } + virtual size_t dispose(Space& home) { + home.ignore(*this,AP_DISPOSE); + x.cancel(home,*this,PC_INT_DOM); + y.cancel(home,*this,PC_INT_DOM); + z.cancel(home,*this,PC_INT_BND); + d.~IntDistance(); + (void) Propagator::dispose(home); + return sizeof(*this); + } + }; + + /// Equality finalizer and zero witness for the pairwise organization + class Finalize : public MixNaryOnePropagator { + protected: + IntDistance d; + IntSharedArray r; + Finalize(Home home, ViewArray& x, IntView z, + const IntDistance& d0, const IntSharedArray& r0) + : MixNaryOnePropagator(home,x,z), d(d0), r(r0) { + home.notice(*this,AP_DISPOSE); + } + Finalize(Space& home, Finalize& p) + : MixNaryOnePropagator(home,p), d(p.d), r(p.r) {} + public: + static ExecStatus post(Home home, ViewArray& x, IntView z, + const IntDistance& d, const IntSharedArray& r) { + (void) new (home) Finalize(home,x,z,d,r); + return ES_OK; + } + virtual Actor* copy(Space& home) { + return new (home) Finalize(home,*this); + } + virtual PropCost cost(const Space&, const ModEventDelta&) const { + return PropCost::quadratic(PropCost::HI,x.size()); + } + virtual ExecStatus propagate(Space& home, const ModEventDelta&) { + if (x.assigned()) { + GECODE_ES_CHECK(assigned(home,x,y,d,r)); + return home.ES_SUBSUMED(*this); + } + if (y.max() != 0) + return ES_FIX; + bool changed = false, realized = false; + GECODE_ES_CHECK(zero(home,x,d,r,changed,realized)); + if (realized) + return home.ES_SUBSUMED(*this); + return changed ? ES_NOFIX : ES_FIX; + } + virtual size_t dispose(Space& home) { + home.ignore(*this,AP_DISPOSE); + d.~IntDistance(); r.~IntSharedArray(); + (void) MixNaryOnePropagator::dispose(home); + return sizeof(*this); + } + }; + + /// Single forward-bound actor with domain advisors and pair witnesses + class AdvisorForward : public Propagator { + protected: + class XAdvisor : public Advisor { + public: + int index; + XAdvisor(Space& home, Propagator& p, Council& c, int i) + : Advisor(home,p,c), index(i) {} + XAdvisor(Space& home, XAdvisor& a) + : Advisor(home,a), index(a.index) {} + }; + ViewArray x; + IntView z; + IntDistance d; + IntSharedArray r; + Council council; + PairCache* cache; + bool* dirty; + int last_min; + bool z_shared; + AdvisorForward(Home home, ViewArray& x0, IntView z0, + const IntDistance& d0, const IntSharedArray& r0) + : Propagator(home), x(x0), z(z0), d(d0), r(r0), council(home), + last_min(-1), z_shared(false) { + home.notice(*this,AP_DISPOSE); + Space& s = home; + int np = static_cast(static_cast(x.size())*(x.size()-1)/2); + cache = s.alloc(np); + for (int i=0; i(x.size()); + for (int i=0; i(static_cast(x.size())*(x.size()-1)/2); + cache = home.alloc(np); + std::copy(p.cache,p.cache+np,cache); + dirty = home.alloc(x.size()); + std::copy(p.dirty,p.dirty+x.size(),dirty); + } + public: + static ExecStatus post(Home home, ViewArray& x, IntView z, + const IntDistance& d, const IntSharedArray& r) { + (void) new (home) AdvisorForward(home,x,z,d,r); + return ES_OK; + } + virtual Actor* copy(Space& home) { + return new (home) AdvisorForward(home,*this); + } + virtual PropCost cost(const Space&, const ModEventDelta&) const { + return PropCost::quadratic(PropCost::HI, + static_cast(x.size())+d.size()); + } + virtual void reschedule(Space& home) { + z.reschedule(home,*this,PC_INT_BND); + // Advisors have no reschedule method; ensure a manual reschedule also + // revisits every pair, even if no new domain event has been delivered. + last_min = -1; + } + virtual ExecStatus advise(Space&, Advisor& a, const Delta&) { + dirty[static_cast(a).index] = true; + return ES_NOFIX; + } + virtual ExecStatus propagate(Space& home, const ModEventDelta&) { + for (;;) { + if (x.assigned()) { + GECODE_ES_CHECK(assigned(home,x,z,d,r)); + return home.ES_SUBSUMED(*this); + } + int zmin = z.min(); + bool all_dirty = zmin != last_min; + bool changed = false; + for (int i=0; i a(council); a(); ++a) + x[a.advisor().index].cancel(home,a.advisor()); + council.dispose(home); + z.cancel(home,*this,PC_INT_BND); + home.free(cache,static_cast(static_cast(x.size())*(x.size()-1)/2)); + home.free(dirty,x.size()); + d.~IntDistance(); r.~IntSharedArray(); + (void) Propagator::dispose(home); + return sizeof(*this); + } + }; + + /// Independent matching-based objective upper bound + class Matching : public MixNaryOnePropagator { + protected: + IntDistance d; + Matching(Home home, ViewArray& x, IntView z, + const IntDistance& d0) + : MixNaryOnePropagator(home,x,z), d(d0) { + home.notice(*this,AP_DISPOSE); + } + Matching(Space& home, Matching& p) + : MixNaryOnePropagator(home,p), d(p.d) {} + bool refuted(int* sites, int n, bool* matched, int threshold) const { + if (threshold == 0) + return false; // Repeated sites are permitted at distance zero. + std::fill(matched,matched+n,false); + int edges = 0; + for (int a=0; a& x, IntView z, + const IntDistance& d) { + if (!z.assigned()) + (void) new (home) Matching(home,x,z,d); + return ES_OK; + } + virtual Actor* copy(Space& home) { + return new (home) Matching(home,*this); + } + virtual PropCost cost(const Space&, const ModEventDelta&) const { + return PropCost::cubic(PropCost::HI,d.size()); + } + virtual ExecStatus propagate(Space& home, const ModEventDelta&) { + if (y.assigned()) + return home.ES_SUBSUMED(*this); + Region region; + bool* present = region.alloc(d.size()); + std::fill(present,present+d.size(),false); + for (int i=0; i v(x[i]); v(); ++v) + present[v.val()] = true; + int* sites = region.alloc(d.size()); + int n = 0; + for (int i=0; i(n); + int lo = y.min(), hi = y.max(); + if (refuted(sites,n,matched,lo)) + return ES_FAILED; + // A failed certificate at t excludes every objective >= t. Greedy + // certificate sizes themselves need not be monotone, so this search + // can miss tighter bounds but cannot delete a feasible objective. + while (lo < hi) { + int mid = lo+(hi-lo+1)/2; + if (refuted(sites,n,matched,mid)) + hi = mid-1; + else + lo = mid; + } + ModEvent me = y.lq(home,hi); + GECODE_ME_CHECK(me); + if (y.assigned()) + return home.ES_SUBSUMED(*this); + return me_modified(me) ? ES_NOFIX : ES_FIX; + } + virtual size_t dispose(Space& home) { + home.ignore(*this,AP_DISPOSE); + d.~IntDistance(); + (void) MixNaryOnePropagator::dispose(home); + return sizeof(*this); + } + }; + + /// Validate the organization and number of positions + void check(const IntVarArgs& x, MinDistancePropKind kind) { + if (x.size() < 2) + throw TooFewArguments("Int::minimum_distance"); + if ((kind != MDP_DECOMPOSED) && (kind != MDP_SINGLE)) + throw IllegalOperation("Int::minimum_distance"); + Limits::nonnegative(static_cast(x.size())*(x.size()-1)/2, + "Int::minimum_distance"); + } + + /// Shared posting for the two public overloads + ExecStatus post(Home home, const IntVarArgs& x, IntView z, + const IntDistance& d, const IntSharedArray& r, + MinDistancePropKind kind, IntPropLevel ipl) { + ViewArray views(home,x); + for (int i=0; i(x.size())*x.size() != r.size()) + throw Int::ArgumentSizeMismatch("Int::minimum_distance"); + for (int i=0; i + * + * Copyright: + * Mikael Zayenz Lagerkvist, 2026 + * + * This file is part of Gecode, the generic constraint + * development environment: + * http://www.gecode.dev + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + +#ifndef GECODE_INT_MIN_DISTANCE_HPP +#define GECODE_INT_MIN_DISTANCE_HPP + +namespace Gecode { + + forceinline int + IntDistance::size(void) const { + return static_cast(object())->n; + } + + forceinline int + IntDistance::operator ()(int a, int b) const { + const Data& d = *static_cast(object()); + assert((a >= 0) && (a < d.n) && (b >= 0) && (b < d.n)); + if (d.matrix) + return d.matrix[a*d.n+b]; + int v = d.function(a,b); + Int::Limits::nonnegative(v,"IntDistance::operator()"); + if ((a == b) && (v != 0)) + throw Int::IllegalOperation("IntDistance::operator()"); + return v; + } + +} + +#endif + +// STATISTICS: int-post diff --git a/test/int/min-distance.cpp b/test/int/min-distance.cpp new file mode 100644 index 0000000000..0959fdc007 --- /dev/null +++ b/test/int/min-distance.cpp @@ -0,0 +1,277 @@ +/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ +/* + * Main authors: + * Mikael Zayenz Lagerkvist + * + * Copyright: + * Mikael Zayenz Lagerkvist, 2026 + * + * This file is part of Gecode, the generic constraint + * development environment: + * http://www.gecode.dev + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + + +#include "test/int.hh" + +#include + +namespace Test { namespace Int { namespace MinDistance { + + /// Distances with both a zero off-diagonal pair and threshold boundaries + Gecode::IntArgs matrix(void) { + return Gecode::IntArgs({0,0,3,4, 0,0,2,1, 3,2,0,4, 4,1,4,0}); + } + + /// Exhaustive assignments and incremental clone/prune checks + class Minimum : public Test { + protected: + int positions; + bool computed, requirements; + int alias; + Gecode::MinDistancePropKind kind; + public: + Minimum(int n, bool f, bool r, int a, + Gecode::MinDistancePropKind k, Gecode::IntPropLevel level) + : Test("MinDistance::"+str(n)+"::"+str(f)+"::"+str(r)+"::"+ + str(a)+"::"+str(k == Gecode::MDP_SINGLE)+"::"+str(level), + n+1,0,4,false,level), + positions(n), computed(f), requirements(r), alias(a), kind(k) { + contest = CTL_NONE; + } + virtual bool solution(const Assignment& a) const { + int minimum = 4; + Gecode::IntArgs m = matrix(); + for (int i=0; i= 4) + return false; + for (int j=i+1; j= 4) + return false; + int first = a[alias == 1 && i == 1 ? 0 : i]; + int second = a[alias == 1 && j == 1 ? 0 : j]; + int distance = m[first*4+second]; + if (requirements && (i == 0) && (j == positions-1) && + (distance < 3)) + return false; + minimum = std::min(minimum,distance); + } + } + return (a[positions] == minimum) && + ((alias != 2) || (a[positions] == a[0])); + } + virtual void post(Gecode::Space& home, Gecode::IntVarArray& a) { + using namespace Gecode; + IntArgs m = matrix(); + IntDistance d = computed ? + IntDistance(4,[m](int i, int j) { return m[i*4+j]; }) : + IntDistance(4,m); + IntVarArgs x(positions); + for (int i=0; i distance) + : x(*this,n,0,sites-1), z(*this,lower,upper) { + Gecode::minimum_distance(*this,x,z, + Gecode::IntDistance(sites,distance),level,kind); + } + Model(Model& s) : Gecode::Space(s) { + x.update(*this,s.x); z.update(*this,s.z); + } + virtual Gecode::Space* copy(void) { return new Model(*this); } + }; + + /// Matching certificates, zero witnesses, and callback lifetime + class Propagation : public Base { + public: + Propagation(void) : Base("Int::MinDistance::Propagation") {} + virtual bool run(void) { + using namespace Gecode; + const MinDistancePropKind kinds[] = {MDP_DECOMPOSED,MDP_SINGLE}; + const IntPropLevel levels[] = {IPL_BASIC,IPL_ADVANCED}; + for (MinDistancePropKind kind : kinds) + for (IntPropLevel level : levels) { + // Forward filtering includes equality at the threshold. + Model forward(2,4,2,4,kind,level, + [](int a, int b) { return std::abs(a-b); }); + rel(forward,forward.x[0],IRT_EQ,0); + if ((forward.status() == SS_FAILED) || + (forward.x[1].min() != 2) || (forward.z.max() != 3)) + return false; + std::unique_ptr clone(static_cast(forward.clone())); + rel(*clone,clone->x[1],IRT_EQ,2); + if ((clone->status() == SS_FAILED) || !clone->z.assigned() || + (clone->z.val() != 2) || forward.z.assigned()) + return false; + + // With only one pair, zero requires equal selections here. + Model zero(2,4,0,0,kind,level, + [](int a, int b) { return std::abs(a-b); }); + dom(zero,zero.x[0],IntSet({0,1})); + dom(zero,zero.x[1],IntSet({1,2})); + if ((zero.status() == SS_FAILED) || + !zero.x[0].assigned() || (zero.x[0].val() != 1) || + !zero.x[1].assigned() || (zero.x[1].val() != 1)) + return false; + + // Assigned objectives still need exact equality, not just >= z. + Model invalid(2,4,1,1,kind,level, + [](int a, int b) { return std::abs(a-b); }); + rel(invalid,invalid.x[0],IRT_EQ,0); + rel(invalid,invalid.x[1],IRT_EQ,3); + if (invalid.status() != SS_FAILED) + return false; + + // One active site can be repeated at objective zero. + Model repeated(3,1,0,3,kind,level, + [](int, int) { return 0; }); + if ((repeated.status() == SS_FAILED) || !repeated.z.assigned() || + (repeated.z.val() != 0)) + return false; + } + + // A perfect conflict matching rules out selecting three sites at 3. + auto conflicts = [](int a, int b) { + return a == b ? 0 : (a/2 == b/2 ? 1 : 3); + }; + for (MinDistancePropKind kind : kinds) { + Model basic(3,4,1,3,kind,IPL_BASIC,conflicts); + Model matching(3,4,1,3,kind,IPL_ADVANCED,conflicts); + if ((basic.status() == SS_FAILED) || (basic.z.max() != 3) || + (matching.status() == SS_FAILED) || (matching.z.max() != 1)) + return false; + } + + // Share a captured object across stable clones and release it with + // the last Space. Computed distances must not build an n*n matrix. + std::weak_ptr lifetime; + std::unique_ptr clone; + { + auto data = std::make_shared(1); + lifetime = data; + Model original(2,1000000,1,3,MDP_SINGLE,IPL_BASIC, + [data](int a, int b) { return a == b ? 0 : *data; }); + // Restrict domains before propagation to avoid enumerating the + // million-site universe; construction itself makes no distance calls. + dom(original,original.x,0,2); + if (original.status() == SS_FAILED) + return false; + clone.reset(static_cast(original.clone())); + } + if (lifetime.expired() || (clone->status() == SS_FAILED)) + return false; + clone.reset(); + if (!lifetime.expired()) + return false; + return true; + } + }; + + /// Matrix and callback validation + class Arguments : public Base { + public: + Arguments(void) : Base("Int::MinDistance::Arguments") {} + virtual bool run(void) { + using namespace Gecode; + try { + IntDistance invalid(2,IntArgs({0,1,2,0})); + return false; + } catch (const Gecode::Int::IllegalOperation&) {} + try { + IntDistance invalid(2,IntArgs({0,-1,-1,0})); + return false; + } catch (const Gecode::Int::OutOfLimits&) {} + try { + IntDistance invalid(2,std::function()); + return false; + } catch (const InvalidFunction&) {} + try { + IntDistance invalid(2,[](int, int) { return -1; }); + (void) invalid(0,1); + return false; + } catch (const Gecode::Int::OutOfLimits&) {} + try { + Model space(2,4,0,4,MDP_DECOMPOSED,IPL_BASIC, + [](int a, int b) { return std::abs(a-b); }); + IntVarArgs x; + IntVar z(space,0,4); + minimum_distance(space,x,z,IntDistance(4,matrix())); + return false; + } catch (const Gecode::Int::TooFewArguments&) {} + return true; + } + }; + + /// Register the compact semantic matrix + class Create { + public: + Create(void) { + const Gecode::MinDistancePropKind kinds[] = + {Gecode::MDP_DECOMPOSED,Gecode::MDP_SINGLE}; + const Gecode::IntPropLevel levels[] = + {Gecode::IPL_BASIC,Gecode::IPL_ADVANCED}; + for (int n : {2,3}) + for (bool computed : {false,true}) + for (bool requirements : {false,true}) + for (Gecode::MinDistancePropKind kind : kinds) + for (Gecode::IntPropLevel level : levels) + (void) new Minimum(n,computed,requirements,0,kind,level); + for (Gecode::MinDistancePropKind kind : kinds) + for (Gecode::IntPropLevel level : levels) + (void) new Minimum(3,true,true,1,kind,level); + for (Gecode::MinDistancePropKind kind : kinds) + for (Gecode::IntPropLevel level : levels) + (void) new Minimum(3,true,false,2,kind,level); + (void) new Propagation; + (void) new Arguments; + } + }; + Create create; + +}}} + +// STATISTICS: test-int From f5d83c4733c301fddbf8103dc0ba4950ef481efd Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Mon, 5 Oct 2026 07:54:27 +0200 Subject: [PATCH 19/23] Track minimum-distance sources in Autoconf dependencies --- Makefile.dep | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/Makefile.dep b/Makefile.dep index d25bd670ba..de68ecb4f6 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -35114,3 +35114,132 @@ test/flatzinc/on_restart_sol_set$(OBJSUFFIX) test/flatzinc/on_restart_sol_set$(S ./gecode/support/static-stack.hpp ./gecode/support/thread.hpp ./gecode/support/thread/thread.hpp \ ./gecode/support/timer.hpp ./test/flatzinc.hh ./test/test.hh \ ./test/test.hpp +gecode/int/min-distance$(OBJSUFFIX) gecode/int/min-distance$(SBJSUFFIX): \ + ./gecode/int.hh ./gecode/int/array-traits.hpp ./gecode/int/array.hpp \ + ./gecode/int/branch.hpp ./gecode/int/branch/action.hpp ./gecode/int/branch/afc.hpp \ + ./gecode/int/branch/assign.hpp ./gecode/int/branch/chb.hpp ./gecode/int/branch/traits.hpp \ + ./gecode/int/branch/val.hpp ./gecode/int/branch/var.hpp ./gecode/int/channel.hpp \ + ./gecode/int/div.hh ./gecode/int/div.hpp ./gecode/int/exception.hpp \ + ./gecode/int/extensional.hpp ./gecode/int/extensional/dfa.hpp ./gecode/int/extensional/tuple-set.hpp \ + ./gecode/int/int-set-1.hpp ./gecode/int/int-set-2.hpp ./gecode/int/ipl.hpp \ + ./gecode/int/irt.hpp ./gecode/int/limits.hpp ./gecode/int/min-distance.hpp \ + ./gecode/int/propagator.hpp ./gecode/int/reify.hpp ./gecode/int/trace.hpp \ + ./gecode/int/trace/bool-delta.hpp ./gecode/int/trace/bool-trace-view.hpp ./gecode/int/trace/int-delta.hpp \ + ./gecode/int/trace/int-trace-view.hpp ./gecode/int/trace/traits.hpp ./gecode/int/var-imp.hpp \ + ./gecode/int/var-imp/bool.hpp ./gecode/int/var-imp/delta.hpp ./gecode/int/var-imp/int.hpp \ + ./gecode/int/var/bool.hpp ./gecode/int/var/int.hpp ./gecode/int/var/print.hpp \ + ./gecode/int/view.hpp ./gecode/int/view/bool-test.hpp ./gecode/int/view/bool.hpp \ + ./gecode/int/view/cached.hpp ./gecode/int/view/constint.hpp ./gecode/int/view/int.hpp \ + ./gecode/int/view/iter.hpp ./gecode/int/view/minus.hpp ./gecode/int/view/neg-bool.hpp \ + ./gecode/int/view/offset.hpp ./gecode/int/view/print.hpp ./gecode/int/view/rel-test.hpp \ + ./gecode/int/view/scale.hpp ./gecode/int/view/zero.hpp ./gecode/iter.hh \ + ./gecode/iter/ranges-add.hpp ./gecode/iter/ranges-append.hpp ./gecode/iter/ranges-array.hpp \ + ./gecode/iter/ranges-cache.hpp ./gecode/iter/ranges-compl.hpp ./gecode/iter/ranges-diff.hpp \ + ./gecode/iter/ranges-empty.hpp ./gecode/iter/ranges-inter.hpp ./gecode/iter/ranges-list.hpp \ + ./gecode/iter/ranges-map.hpp ./gecode/iter/ranges-minmax.hpp ./gecode/iter/ranges-minus.hpp \ + ./gecode/iter/ranges-negative.hpp ./gecode/iter/ranges-offset.hpp ./gecode/iter/ranges-operations.hpp \ + ./gecode/iter/ranges-positive.hpp ./gecode/iter/ranges-rangelist.hpp ./gecode/iter/ranges-scale.hpp \ + ./gecode/iter/ranges-singleton-append.hpp ./gecode/iter/ranges-singleton.hpp ./gecode/iter/ranges-size.hpp \ + ./gecode/iter/ranges-union.hpp ./gecode/iter/ranges-values.hpp ./gecode/iter/values-array.hpp \ + ./gecode/iter/values-bitset.hpp ./gecode/iter/values-bitsetoffset.hpp ./gecode/iter/values-inter.hpp \ + ./gecode/iter/values-list.hpp ./gecode/iter/values-map.hpp ./gecode/iter/values-minus.hpp \ + ./gecode/iter/values-negative.hpp ./gecode/iter/values-offset.hpp ./gecode/iter/values-positive.hpp \ + ./gecode/iter/values-ranges.hpp ./gecode/iter/values-singleton.hpp ./gecode/iter/values-union.hpp \ + ./gecode/iter/values-unique.hpp ./gecode/kernel.hh ./gecode/kernel/archive.hpp \ + ./gecode/kernel/branch/action.hpp ./gecode/kernel/branch/afc.hpp ./gecode/kernel/branch/chb.hpp \ + ./gecode/kernel/branch/filter.hpp ./gecode/kernel/branch/merit.hpp ./gecode/kernel/branch/print.hpp \ + ./gecode/kernel/branch/tiebreak.hpp ./gecode/kernel/branch/traits.hpp ./gecode/kernel/branch/val-commit.hpp \ + ./gecode/kernel/branch/val-sel-commit.hpp ./gecode/kernel/branch/val-sel.hpp ./gecode/kernel/branch/val.hpp \ + ./gecode/kernel/branch/var.hpp ./gecode/kernel/branch/view-sel.hpp ./gecode/kernel/branch/view-val.hpp \ + ./gecode/kernel/branch/view.hpp ./gecode/kernel/core.hpp ./gecode/kernel/data/array.hpp \ + ./gecode/kernel/data/rnd.hpp ./gecode/kernel/data/shared-array.hpp ./gecode/kernel/data/shared-data.hpp \ + ./gecode/kernel/exception.hpp ./gecode/kernel/gpi.hpp ./gecode/kernel/macros.hpp \ + ./gecode/kernel/memory/allocators.hpp ./gecode/kernel/memory/config.hpp ./gecode/kernel/memory/manager.hpp \ + ./gecode/kernel/memory/region.hpp ./gecode/kernel/modevent.hpp ./gecode/kernel/propagator/advisor.hpp \ + ./gecode/kernel/propagator/pattern.hpp ./gecode/kernel/propagator/subscribed.hpp ./gecode/kernel/propagator/wait.hpp \ + ./gecode/kernel/range-list.hpp ./gecode/kernel/shared-object.hpp ./gecode/kernel/shared-space-data.hpp \ + ./gecode/kernel/trace/filter.hpp ./gecode/kernel/trace/general.hpp ./gecode/kernel/trace/print.hpp \ + ./gecode/kernel/trace/recorder.hpp ./gecode/kernel/trace/tracer.hpp ./gecode/kernel/trace/traits.hpp \ + ./gecode/kernel/var-imp.hpp ./gecode/kernel/var-type.hpp ./gecode/kernel/var.hpp \ + ./gecode/kernel/view.hpp ./gecode/search.hh ./gecode/search/bab.hpp \ + ./gecode/search/base.hpp ./gecode/search/build.hpp ./gecode/search/cutoff.hpp \ + ./gecode/search/dfs.hpp ./gecode/search/engine.hpp ./gecode/search/exception.hpp \ + ./gecode/search/lds.hpp ./gecode/search/options.hpp ./gecode/search/pbs.hpp \ + ./gecode/search/rbs.hpp ./gecode/search/sebs.hpp ./gecode/search/seq/dead.hh \ + ./gecode/search/statistics.hpp ./gecode/search/stop.hpp ./gecode/search/support.hh \ + ./gecode/search/trace-recorder.hpp ./gecode/search/tracer.hpp ./gecode/search/traits.hpp \ + ./gecode/support.hh ./gecode/support/allocator.hpp ./gecode/support/auto-link.hpp \ + ./gecode/support/bitset-base.hpp ./gecode/support/bitset-offset.hpp ./gecode/support/bitset.hpp \ + ./gecode/support/block-allocator.hpp ./gecode/support/cast.hpp gecode/support/config.hpp \ + ./gecode/support/dynamic-array.hpp ./gecode/support/dynamic-queue.hpp ./gecode/support/dynamic-stack.hpp \ + ./gecode/support/exception.hpp ./gecode/support/failpoint.hpp ./gecode/support/hash.hpp \ + ./gecode/support/heap.hpp ./gecode/support/hw-rnd.hpp ./gecode/support/int-type.hpp \ + ./gecode/support/macros.hpp ./gecode/support/marked-pointer.hpp ./gecode/support/random.hpp \ + ./gecode/support/ref-count.hpp ./gecode/support/run-jobs.hpp ./gecode/support/sort.hpp \ + ./gecode/support/static-stack.hpp ./gecode/support/thread.hpp ./gecode/support/thread/thread.hpp \ + ./gecode/support/timer.hpp +test/int/min-distance$(OBJSUFFIX) test/int/min-distance$(SBJSUFFIX): \ + ./gecode/int.hh ./gecode/int/array-traits.hpp ./gecode/int/array.hpp \ + ./gecode/int/branch.hpp ./gecode/int/branch/action.hpp ./gecode/int/branch/afc.hpp \ + ./gecode/int/branch/assign.hpp ./gecode/int/branch/chb.hpp ./gecode/int/branch/traits.hpp \ + ./gecode/int/branch/val.hpp ./gecode/int/branch/var.hpp ./gecode/int/channel.hpp \ + ./gecode/int/div.hh ./gecode/int/div.hpp ./gecode/int/exception.hpp \ + ./gecode/int/extensional.hpp ./gecode/int/extensional/dfa.hpp ./gecode/int/extensional/tuple-set.hpp \ + ./gecode/int/int-set-1.hpp ./gecode/int/int-set-2.hpp ./gecode/int/ipl.hpp \ + ./gecode/int/irt.hpp ./gecode/int/limits.hpp ./gecode/int/min-distance.hpp \ + ./gecode/int/propagator.hpp ./gecode/int/reify.hpp ./gecode/int/trace.hpp \ + ./gecode/int/trace/bool-delta.hpp ./gecode/int/trace/bool-trace-view.hpp ./gecode/int/trace/int-delta.hpp \ + ./gecode/int/trace/int-trace-view.hpp ./gecode/int/trace/traits.hpp ./gecode/int/var-imp.hpp \ + ./gecode/int/var-imp/bool.hpp ./gecode/int/var-imp/delta.hpp ./gecode/int/var-imp/int.hpp \ + ./gecode/int/var/bool.hpp ./gecode/int/var/int.hpp ./gecode/int/var/print.hpp \ + ./gecode/int/view.hpp ./gecode/int/view/bool-test.hpp ./gecode/int/view/bool.hpp \ + ./gecode/int/view/cached.hpp ./gecode/int/view/constint.hpp ./gecode/int/view/int.hpp \ + ./gecode/int/view/iter.hpp ./gecode/int/view/minus.hpp ./gecode/int/view/neg-bool.hpp \ + ./gecode/int/view/offset.hpp ./gecode/int/view/print.hpp ./gecode/int/view/rel-test.hpp \ + ./gecode/int/view/scale.hpp ./gecode/int/view/zero.hpp ./gecode/iter.hh \ + ./gecode/iter/ranges-add.hpp ./gecode/iter/ranges-append.hpp ./gecode/iter/ranges-array.hpp \ + ./gecode/iter/ranges-cache.hpp ./gecode/iter/ranges-compl.hpp ./gecode/iter/ranges-diff.hpp \ + ./gecode/iter/ranges-empty.hpp ./gecode/iter/ranges-inter.hpp ./gecode/iter/ranges-list.hpp \ + ./gecode/iter/ranges-map.hpp ./gecode/iter/ranges-minmax.hpp ./gecode/iter/ranges-minus.hpp \ + ./gecode/iter/ranges-negative.hpp ./gecode/iter/ranges-offset.hpp ./gecode/iter/ranges-operations.hpp \ + ./gecode/iter/ranges-positive.hpp ./gecode/iter/ranges-rangelist.hpp ./gecode/iter/ranges-scale.hpp \ + ./gecode/iter/ranges-singleton-append.hpp ./gecode/iter/ranges-singleton.hpp ./gecode/iter/ranges-size.hpp \ + ./gecode/iter/ranges-union.hpp ./gecode/iter/ranges-values.hpp ./gecode/iter/values-array.hpp \ + ./gecode/iter/values-bitset.hpp ./gecode/iter/values-bitsetoffset.hpp ./gecode/iter/values-inter.hpp \ + ./gecode/iter/values-list.hpp ./gecode/iter/values-map.hpp ./gecode/iter/values-minus.hpp \ + ./gecode/iter/values-negative.hpp ./gecode/iter/values-offset.hpp ./gecode/iter/values-positive.hpp \ + ./gecode/iter/values-ranges.hpp ./gecode/iter/values-singleton.hpp ./gecode/iter/values-union.hpp \ + ./gecode/iter/values-unique.hpp ./gecode/kernel.hh ./gecode/kernel/archive.hpp \ + ./gecode/kernel/branch/action.hpp ./gecode/kernel/branch/afc.hpp ./gecode/kernel/branch/chb.hpp \ + ./gecode/kernel/branch/filter.hpp ./gecode/kernel/branch/merit.hpp ./gecode/kernel/branch/print.hpp \ + ./gecode/kernel/branch/tiebreak.hpp ./gecode/kernel/branch/traits.hpp ./gecode/kernel/branch/val-commit.hpp \ + ./gecode/kernel/branch/val-sel-commit.hpp ./gecode/kernel/branch/val-sel.hpp ./gecode/kernel/branch/val.hpp \ + ./gecode/kernel/branch/var.hpp ./gecode/kernel/branch/view-sel.hpp ./gecode/kernel/branch/view-val.hpp \ + ./gecode/kernel/branch/view.hpp ./gecode/kernel/core.hpp ./gecode/kernel/data/array.hpp \ + ./gecode/kernel/data/rnd.hpp ./gecode/kernel/data/shared-array.hpp ./gecode/kernel/data/shared-data.hpp \ + ./gecode/kernel/exception.hpp ./gecode/kernel/gpi.hpp ./gecode/kernel/macros.hpp \ + ./gecode/kernel/memory/allocators.hpp ./gecode/kernel/memory/config.hpp ./gecode/kernel/memory/manager.hpp \ + ./gecode/kernel/memory/region.hpp ./gecode/kernel/modevent.hpp ./gecode/kernel/propagator/advisor.hpp \ + ./gecode/kernel/propagator/pattern.hpp ./gecode/kernel/propagator/subscribed.hpp ./gecode/kernel/propagator/wait.hpp \ + ./gecode/kernel/range-list.hpp ./gecode/kernel/shared-object.hpp ./gecode/kernel/shared-space-data.hpp \ + ./gecode/kernel/trace/filter.hpp ./gecode/kernel/trace/general.hpp ./gecode/kernel/trace/print.hpp \ + ./gecode/kernel/trace/recorder.hpp ./gecode/kernel/trace/tracer.hpp ./gecode/kernel/trace/traits.hpp \ + ./gecode/kernel/var-imp.hpp ./gecode/kernel/var-type.hpp ./gecode/kernel/var.hpp \ + ./gecode/kernel/view.hpp ./gecode/search.hh ./gecode/search/bab.hpp \ + ./gecode/search/base.hpp ./gecode/search/build.hpp ./gecode/search/cutoff.hpp \ + ./gecode/search/dfs.hpp ./gecode/search/engine.hpp ./gecode/search/exception.hpp \ + ./gecode/search/lds.hpp ./gecode/search/options.hpp ./gecode/search/pbs.hpp \ + ./gecode/search/rbs.hpp ./gecode/search/sebs.hpp ./gecode/search/seq/dead.hh \ + ./gecode/search/statistics.hpp ./gecode/search/stop.hpp ./gecode/search/support.hh \ + ./gecode/search/trace-recorder.hpp ./gecode/search/tracer.hpp ./gecode/search/traits.hpp \ + ./gecode/support.hh ./gecode/support/allocator.hpp ./gecode/support/auto-link.hpp \ + ./gecode/support/bitset-base.hpp ./gecode/support/bitset-offset.hpp ./gecode/support/bitset.hpp \ + ./gecode/support/block-allocator.hpp ./gecode/support/cast.hpp gecode/support/config.hpp \ + ./gecode/support/dynamic-array.hpp ./gecode/support/dynamic-queue.hpp ./gecode/support/dynamic-stack.hpp \ + ./gecode/support/exception.hpp ./gecode/support/failpoint.hpp ./gecode/support/hash.hpp \ + ./gecode/support/heap.hpp ./gecode/support/hw-rnd.hpp ./gecode/support/int-type.hpp \ + ./gecode/support/macros.hpp ./gecode/support/marked-pointer.hpp ./gecode/support/random.hpp \ + ./gecode/support/ref-count.hpp ./gecode/support/run-jobs.hpp ./gecode/support/sort.hpp \ + ./gecode/support/static-stack.hpp ./gecode/support/thread.hpp ./gecode/support/thread/thread.hpp \ + ./gecode/support/timer.hpp ./test/int.hh ./test/int.hpp \ + ./test/test.hh ./test/test.hpp From ea16845ebf2519bfc018b9e78a2aeb148ee1d0d4 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Mon, 5 Oct 2026 17:27:16 +0200 Subject: [PATCH 20/23] Declare each variable separately --- gecode/int/min-distance.cpp | 18 +++++++++++++----- test/int/min-distance.cpp | 3 ++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/gecode/int/min-distance.cpp b/gecode/int/min-distance.cpp index f8a1f34d91..278bb12b8d 100644 --- a/gecode/int/min-distance.cpp +++ b/gecode/int/min-distance.cpp @@ -109,7 +109,9 @@ namespace Gecode { namespace Int { namespace MinDistance { /// Pair maximum and its witness struct PairCache { - int a, b, upper; + int a; + int b; + int upper; }; /// Recompute the maximum distance between current domains @@ -145,7 +147,9 @@ namespace Gecode { namespace Int { namespace MinDistance { ExecStatus zero(Space& home, const ViewArray& x, const IntDistance& d, const IntSharedArray& r, bool& changed, bool& realized) { - int count = 0, first = -1, second = -1; + int count = 0; + int first = -1; + int second = -1; for (int i=0; i(n); - int lo = y.min(), hi = y.max(); + int lo = y.min(); + int hi = y.max(); if (refuted(sites,n,matched,lo)) return ES_FAILED; // A failed certificate at t excludes every objective >= t. Greedy diff --git a/test/int/min-distance.cpp b/test/int/min-distance.cpp index 0959fdc007..51ae53753d 100644 --- a/test/int/min-distance.cpp +++ b/test/int/min-distance.cpp @@ -48,7 +48,8 @@ namespace Test { namespace Int { namespace MinDistance { class Minimum : public Test { protected: int positions; - bool computed, requirements; + bool computed; + bool requirements; int alias; Gecode::MinDistancePropKind kind; public: From 5fb80d285f587b562973490a9d301cb78058bd13 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Fri, 9 Oct 2026 08:23:14 +0200 Subject: [PATCH 21/23] Keep minimum-distance tests in the tagged check selection --- test/int/min-distance.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/int/min-distance.cpp b/test/int/min-distance.cpp index 51ae53753d..be9b982cdf 100644 --- a/test/int/min-distance.cpp +++ b/test/int/min-distance.cpp @@ -55,7 +55,8 @@ namespace Test { namespace Int { namespace MinDistance { public: Minimum(int n, bool f, bool r, int a, Gecode::MinDistancePropKind k, Gecode::IntPropLevel level) - : Test("MinDistance::"+str(n)+"::"+str(f)+"::"+str(r)+"::"+ + : Test(TestTags(TestTag::normal,TestTag::check), + "MinDistance::"+str(n)+"::"+str(f)+"::"+str(r)+"::"+ str(a)+"::"+str(k == Gecode::MDP_SINGLE)+"::"+str(level), n+1,0,4,false,level), positions(n), computed(f), requirements(r), alias(a), kind(k) { @@ -129,7 +130,8 @@ namespace Test { namespace Int { namespace MinDistance { /// Matching certificates, zero witnesses, and callback lifetime class Propagation : public Base { public: - Propagation(void) : Base("Int::MinDistance::Propagation") {} + Propagation(void) : Base("Int::MinDistance::Propagation", + TestTags(TestTag::normal,TestTag::check)) {} virtual bool run(void) { using namespace Gecode; const MinDistancePropKind kinds[] = {MDP_DECOMPOSED,MDP_SINGLE}; @@ -215,7 +217,8 @@ namespace Test { namespace Int { namespace MinDistance { /// Matrix and callback validation class Arguments : public Base { public: - Arguments(void) : Base("Int::MinDistance::Arguments") {} + Arguments(void) : Base("Int::MinDistance::Arguments", + TestTags(TestTag::normal,TestTag::check)) {} virtual bool run(void) { using namespace Gecode; try { From 5e8e01b3eab1d0cbb9fb62461d493018c5782ea5 Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Fri, 9 Oct 2026 14:54:49 +0200 Subject: [PATCH 22/23] Use the check preset for minimum-distance tests --- test/int/min-distance.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/int/min-distance.cpp b/test/int/min-distance.cpp index be9b982cdf..d993efc72a 100644 --- a/test/int/min-distance.cpp +++ b/test/int/min-distance.cpp @@ -55,7 +55,7 @@ namespace Test { namespace Int { namespace MinDistance { public: Minimum(int n, bool f, bool r, int a, Gecode::MinDistancePropKind k, Gecode::IntPropLevel level) - : Test(TestTags(TestTag::normal,TestTag::check), + : Test(TestTags::check(), "MinDistance::"+str(n)+"::"+str(f)+"::"+str(r)+"::"+ str(a)+"::"+str(k == Gecode::MDP_SINGLE)+"::"+str(level), n+1,0,4,false,level), @@ -131,7 +131,7 @@ namespace Test { namespace Int { namespace MinDistance { class Propagation : public Base { public: Propagation(void) : Base("Int::MinDistance::Propagation", - TestTags(TestTag::normal,TestTag::check)) {} + TestTags::check()) {} virtual bool run(void) { using namespace Gecode; const MinDistancePropKind kinds[] = {MDP_DECOMPOSED,MDP_SINGLE}; @@ -218,7 +218,7 @@ namespace Test { namespace Int { namespace MinDistance { class Arguments : public Base { public: Arguments(void) : Base("Int::MinDistance::Arguments", - TestTags(TestTag::normal,TestTag::check)) {} + TestTags::check()) {} virtual bool run(void) { using namespace Gecode; try { From 4371bcf246988c40f34ff3a4a7ab5c265888fa5b Mon Sep 17 00:00:00 2001 From: Mikael Zayenz Lagerkvist Date: Mon, 12 Oct 2026 16:33:49 +0200 Subject: [PATCH 23/23] Align minimum-distance propagators with Gecode conventions --- Makefile.dep | 93 +++--- Makefile.in | 3 +- gecode/int/min-distance.cpp | 486 +---------------------------- gecode/int/min-distance.hh | 222 +++++++++++++ gecode/int/min-distance/prop.hpp | 519 +++++++++++++++++++++++++++++++ 5 files changed, 792 insertions(+), 531 deletions(-) create mode 100644 gecode/int/min-distance.hh create mode 100644 gecode/int/min-distance/prop.hpp diff --git a/Makefile.dep b/Makefile.dep index de68ecb4f6..1ea49eac45 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -35122,52 +35122,53 @@ gecode/int/min-distance$(OBJSUFFIX) gecode/int/min-distance$(SBJSUFFIX): \ ./gecode/int/div.hh ./gecode/int/div.hpp ./gecode/int/exception.hpp \ ./gecode/int/extensional.hpp ./gecode/int/extensional/dfa.hpp ./gecode/int/extensional/tuple-set.hpp \ ./gecode/int/int-set-1.hpp ./gecode/int/int-set-2.hpp ./gecode/int/ipl.hpp \ - ./gecode/int/irt.hpp ./gecode/int/limits.hpp ./gecode/int/min-distance.hpp \ - ./gecode/int/propagator.hpp ./gecode/int/reify.hpp ./gecode/int/trace.hpp \ - ./gecode/int/trace/bool-delta.hpp ./gecode/int/trace/bool-trace-view.hpp ./gecode/int/trace/int-delta.hpp \ - ./gecode/int/trace/int-trace-view.hpp ./gecode/int/trace/traits.hpp ./gecode/int/var-imp.hpp \ - ./gecode/int/var-imp/bool.hpp ./gecode/int/var-imp/delta.hpp ./gecode/int/var-imp/int.hpp \ - ./gecode/int/var/bool.hpp ./gecode/int/var/int.hpp ./gecode/int/var/print.hpp \ - ./gecode/int/view.hpp ./gecode/int/view/bool-test.hpp ./gecode/int/view/bool.hpp \ - ./gecode/int/view/cached.hpp ./gecode/int/view/constint.hpp ./gecode/int/view/int.hpp \ - ./gecode/int/view/iter.hpp ./gecode/int/view/minus.hpp ./gecode/int/view/neg-bool.hpp \ - ./gecode/int/view/offset.hpp ./gecode/int/view/print.hpp ./gecode/int/view/rel-test.hpp \ - ./gecode/int/view/scale.hpp ./gecode/int/view/zero.hpp ./gecode/iter.hh \ - ./gecode/iter/ranges-add.hpp ./gecode/iter/ranges-append.hpp ./gecode/iter/ranges-array.hpp \ - ./gecode/iter/ranges-cache.hpp ./gecode/iter/ranges-compl.hpp ./gecode/iter/ranges-diff.hpp \ - ./gecode/iter/ranges-empty.hpp ./gecode/iter/ranges-inter.hpp ./gecode/iter/ranges-list.hpp \ - ./gecode/iter/ranges-map.hpp ./gecode/iter/ranges-minmax.hpp ./gecode/iter/ranges-minus.hpp \ - ./gecode/iter/ranges-negative.hpp ./gecode/iter/ranges-offset.hpp ./gecode/iter/ranges-operations.hpp \ - ./gecode/iter/ranges-positive.hpp ./gecode/iter/ranges-rangelist.hpp ./gecode/iter/ranges-scale.hpp \ - ./gecode/iter/ranges-singleton-append.hpp ./gecode/iter/ranges-singleton.hpp ./gecode/iter/ranges-size.hpp \ - ./gecode/iter/ranges-union.hpp ./gecode/iter/ranges-values.hpp ./gecode/iter/values-array.hpp \ - ./gecode/iter/values-bitset.hpp ./gecode/iter/values-bitsetoffset.hpp ./gecode/iter/values-inter.hpp \ - ./gecode/iter/values-list.hpp ./gecode/iter/values-map.hpp ./gecode/iter/values-minus.hpp \ - ./gecode/iter/values-negative.hpp ./gecode/iter/values-offset.hpp ./gecode/iter/values-positive.hpp \ - ./gecode/iter/values-ranges.hpp ./gecode/iter/values-singleton.hpp ./gecode/iter/values-union.hpp \ - ./gecode/iter/values-unique.hpp ./gecode/kernel.hh ./gecode/kernel/archive.hpp \ - ./gecode/kernel/branch/action.hpp ./gecode/kernel/branch/afc.hpp ./gecode/kernel/branch/chb.hpp \ - ./gecode/kernel/branch/filter.hpp ./gecode/kernel/branch/merit.hpp ./gecode/kernel/branch/print.hpp \ - ./gecode/kernel/branch/tiebreak.hpp ./gecode/kernel/branch/traits.hpp ./gecode/kernel/branch/val-commit.hpp \ - ./gecode/kernel/branch/val-sel-commit.hpp ./gecode/kernel/branch/val-sel.hpp ./gecode/kernel/branch/val.hpp \ - ./gecode/kernel/branch/var.hpp ./gecode/kernel/branch/view-sel.hpp ./gecode/kernel/branch/view-val.hpp \ - ./gecode/kernel/branch/view.hpp ./gecode/kernel/core.hpp ./gecode/kernel/data/array.hpp \ - ./gecode/kernel/data/rnd.hpp ./gecode/kernel/data/shared-array.hpp ./gecode/kernel/data/shared-data.hpp \ - ./gecode/kernel/exception.hpp ./gecode/kernel/gpi.hpp ./gecode/kernel/macros.hpp \ - ./gecode/kernel/memory/allocators.hpp ./gecode/kernel/memory/config.hpp ./gecode/kernel/memory/manager.hpp \ - ./gecode/kernel/memory/region.hpp ./gecode/kernel/modevent.hpp ./gecode/kernel/propagator/advisor.hpp \ - ./gecode/kernel/propagator/pattern.hpp ./gecode/kernel/propagator/subscribed.hpp ./gecode/kernel/propagator/wait.hpp \ - ./gecode/kernel/range-list.hpp ./gecode/kernel/shared-object.hpp ./gecode/kernel/shared-space-data.hpp \ - ./gecode/kernel/trace/filter.hpp ./gecode/kernel/trace/general.hpp ./gecode/kernel/trace/print.hpp \ - ./gecode/kernel/trace/recorder.hpp ./gecode/kernel/trace/tracer.hpp ./gecode/kernel/trace/traits.hpp \ - ./gecode/kernel/var-imp.hpp ./gecode/kernel/var-type.hpp ./gecode/kernel/var.hpp \ - ./gecode/kernel/view.hpp ./gecode/search.hh ./gecode/search/bab.hpp \ - ./gecode/search/base.hpp ./gecode/search/build.hpp ./gecode/search/cutoff.hpp \ - ./gecode/search/dfs.hpp ./gecode/search/engine.hpp ./gecode/search/exception.hpp \ - ./gecode/search/lds.hpp ./gecode/search/options.hpp ./gecode/search/pbs.hpp \ - ./gecode/search/rbs.hpp ./gecode/search/sebs.hpp ./gecode/search/seq/dead.hh \ - ./gecode/search/statistics.hpp ./gecode/search/stop.hpp ./gecode/search/support.hh \ - ./gecode/search/trace-recorder.hpp ./gecode/search/tracer.hpp ./gecode/search/traits.hpp \ + ./gecode/int/irt.hpp ./gecode/int/limits.hpp ./gecode/int/min-distance.hh \ + ./gecode/int/min-distance.hpp ./gecode/int/min-distance/prop.hpp ./gecode/int/propagator.hpp \ + ./gecode/int/reify.hpp ./gecode/int/trace.hpp ./gecode/int/trace/bool-delta.hpp \ + ./gecode/int/trace/bool-trace-view.hpp ./gecode/int/trace/int-delta.hpp ./gecode/int/trace/int-trace-view.hpp \ + ./gecode/int/trace/traits.hpp ./gecode/int/var-imp.hpp ./gecode/int/var-imp/bool.hpp \ + ./gecode/int/var-imp/delta.hpp ./gecode/int/var-imp/int.hpp ./gecode/int/var/bool.hpp \ + ./gecode/int/var/int.hpp ./gecode/int/var/print.hpp ./gecode/int/view.hpp \ + ./gecode/int/view/bool-test.hpp ./gecode/int/view/bool.hpp ./gecode/int/view/cached.hpp \ + ./gecode/int/view/constint.hpp ./gecode/int/view/int.hpp ./gecode/int/view/iter.hpp \ + ./gecode/int/view/minus.hpp ./gecode/int/view/neg-bool.hpp ./gecode/int/view/offset.hpp \ + ./gecode/int/view/print.hpp ./gecode/int/view/rel-test.hpp ./gecode/int/view/scale.hpp \ + ./gecode/int/view/zero.hpp ./gecode/iter.hh ./gecode/iter/ranges-add.hpp \ + ./gecode/iter/ranges-append.hpp ./gecode/iter/ranges-array.hpp ./gecode/iter/ranges-cache.hpp \ + ./gecode/iter/ranges-compl.hpp ./gecode/iter/ranges-diff.hpp ./gecode/iter/ranges-empty.hpp \ + ./gecode/iter/ranges-inter.hpp ./gecode/iter/ranges-list.hpp ./gecode/iter/ranges-map.hpp \ + ./gecode/iter/ranges-minmax.hpp ./gecode/iter/ranges-minus.hpp ./gecode/iter/ranges-negative.hpp \ + ./gecode/iter/ranges-offset.hpp ./gecode/iter/ranges-operations.hpp ./gecode/iter/ranges-positive.hpp \ + ./gecode/iter/ranges-rangelist.hpp ./gecode/iter/ranges-scale.hpp ./gecode/iter/ranges-singleton-append.hpp \ + ./gecode/iter/ranges-singleton.hpp ./gecode/iter/ranges-size.hpp ./gecode/iter/ranges-union.hpp \ + ./gecode/iter/ranges-values.hpp ./gecode/iter/values-array.hpp ./gecode/iter/values-bitset.hpp \ + ./gecode/iter/values-bitsetoffset.hpp ./gecode/iter/values-inter.hpp ./gecode/iter/values-list.hpp \ + ./gecode/iter/values-map.hpp ./gecode/iter/values-minus.hpp ./gecode/iter/values-negative.hpp \ + ./gecode/iter/values-offset.hpp ./gecode/iter/values-positive.hpp ./gecode/iter/values-ranges.hpp \ + ./gecode/iter/values-singleton.hpp ./gecode/iter/values-union.hpp ./gecode/iter/values-unique.hpp \ + ./gecode/kernel.hh ./gecode/kernel/archive.hpp ./gecode/kernel/branch/action.hpp \ + ./gecode/kernel/branch/afc.hpp ./gecode/kernel/branch/chb.hpp ./gecode/kernel/branch/filter.hpp \ + ./gecode/kernel/branch/merit.hpp ./gecode/kernel/branch/print.hpp ./gecode/kernel/branch/tiebreak.hpp \ + ./gecode/kernel/branch/traits.hpp ./gecode/kernel/branch/val-commit.hpp ./gecode/kernel/branch/val-sel-commit.hpp \ + ./gecode/kernel/branch/val-sel.hpp ./gecode/kernel/branch/val.hpp ./gecode/kernel/branch/var.hpp \ + ./gecode/kernel/branch/view-sel.hpp ./gecode/kernel/branch/view-val.hpp ./gecode/kernel/branch/view.hpp \ + ./gecode/kernel/core.hpp ./gecode/kernel/data/array.hpp ./gecode/kernel/data/rnd.hpp \ + ./gecode/kernel/data/shared-array.hpp ./gecode/kernel/data/shared-data.hpp ./gecode/kernel/exception.hpp \ + ./gecode/kernel/gpi.hpp ./gecode/kernel/macros.hpp ./gecode/kernel/memory/allocators.hpp \ + ./gecode/kernel/memory/config.hpp ./gecode/kernel/memory/manager.hpp ./gecode/kernel/memory/region.hpp \ + ./gecode/kernel/modevent.hpp ./gecode/kernel/propagator/advisor.hpp ./gecode/kernel/propagator/pattern.hpp \ + ./gecode/kernel/propagator/subscribed.hpp ./gecode/kernel/propagator/wait.hpp ./gecode/kernel/range-list.hpp \ + ./gecode/kernel/shared-object.hpp ./gecode/kernel/shared-space-data.hpp ./gecode/kernel/trace/filter.hpp \ + ./gecode/kernel/trace/general.hpp ./gecode/kernel/trace/print.hpp ./gecode/kernel/trace/recorder.hpp \ + ./gecode/kernel/trace/tracer.hpp ./gecode/kernel/trace/traits.hpp ./gecode/kernel/var-imp.hpp \ + ./gecode/kernel/var-type.hpp ./gecode/kernel/var.hpp ./gecode/kernel/view.hpp \ + ./gecode/search.hh ./gecode/search/bab.hpp ./gecode/search/base.hpp \ + ./gecode/search/build.hpp ./gecode/search/cutoff.hpp ./gecode/search/dfs.hpp \ + ./gecode/search/engine.hpp ./gecode/search/exception.hpp ./gecode/search/lds.hpp \ + ./gecode/search/options.hpp ./gecode/search/pbs.hpp ./gecode/search/rbs.hpp \ + ./gecode/search/sebs.hpp ./gecode/search/seq/dead.hh ./gecode/search/statistics.hpp \ + ./gecode/search/stop.hpp ./gecode/search/support.hh ./gecode/search/trace-recorder.hpp \ + ./gecode/search/tracer.hpp ./gecode/search/traits.hpp ./gecode/search/worker-control.hh \ ./gecode/support.hh ./gecode/support/allocator.hpp ./gecode/support/auto-link.hpp \ ./gecode/support/bitset-base.hpp ./gecode/support/bitset-offset.hpp ./gecode/support/bitset.hpp \ ./gecode/support/block-allocator.hpp ./gecode/support/cast.hpp gecode/support/config.hpp \ diff --git a/Makefile.in b/Makefile.in index 60334f8678..26d8c94e77 100755 --- a/Makefile.in +++ b/Makefile.in @@ -398,7 +398,8 @@ INTHDR0 = \ view/offset.hpp view/rel-test.hpp view/scale.hpp view/iter.hpp \ arithmetic.hh array.hpp array-traits.hpp bool.hh branch.hh \ distinct.hh dom.hh \ - element.hh min-distance.hpp exception.hpp gcc.hh linear.hh \ + element.hh min-distance.hh min-distance.hpp min-distance/prop.hpp \ + exception.hpp gcc.hh linear.hh \ reify.hpp propagator.hpp extensional.hh rel.hh \ sorted.hh var-imp.hpp view.hpp ipl.hpp irt.hpp \ channel.hh channel.hpp channel/dom.hpp channel/val.hpp \ diff --git a/gecode/int/min-distance.cpp b/gecode/int/min-distance.cpp index 278bb12b8d..cfe9bf549d 100644 --- a/gecode/int/min-distance.cpp +++ b/gecode/int/min-distance.cpp @@ -32,9 +32,8 @@ */ -#include +#include -#include #include namespace Gecode { @@ -70,489 +69,8 @@ namespace Gecode { } -/** - * \namespace Gecode::Int::MinDistance - * - * The forward-bound and greedy conflict-matching algorithms follow: - * M. Z. Lagerkvist, Propagation Algorithms for the Minimum-Distance - * Constraint over Selected Points, ModRef 2026. - * https://github.com/zayenz/modref2026-minimum-distance-propagators - * - * \brief Minimum-distance propagators over indexed sites - */ namespace Gecode { namespace Int { namespace MinDistance { - /// Inclusive requirement, with an empty matrix denoting all zeroes - forceinline int - requirement(const IntSharedArray& r, int n, int i, int j) { - return !r ? 0 : r[i*n+j]; - } - - /// Prune the partner of an assigned endpoint - ExecStatus - forward(Space& home, IntView a, IntView b, int threshold, - const IntDistance& d, bool& changed) { - Region region; - int* remove = region.alloc(b.size()); - int nr = 0; - for (ViewValues v(b); v(); ++v) - if (d(a.val(),v.val()) < threshold) - remove[nr++] = v.val(); - if (nr != 0) { - Iter::Values::Array values(remove,static_cast(nr)); - ModEvent me = b.minus_v(home,values,false); - GECODE_ME_CHECK(me); - changed |= me_modified(me); - } - return ES_OK; - } - - /// Pair maximum and its witness - struct PairCache { - int a; - int b; - int upper; - }; - - /// Recompute the maximum distance between current domains - void - pair_max(IntView x, IntView y, const IntDistance& d, PairCache& c) { - c.upper = -1; - for (ViewValues a(x); a(); ++a) - for (ViewValues b(y); b(); ++b) { - int v = d(a.val(),b.val()); - if (v > c.upper) { - c.a = a.val(); c.b = b.val(); c.upper = v; - } - } - } - - /// Validate and bind a complete assignment - ExecStatus - assigned(Space& home, const ViewArray& x, IntView z, - const IntDistance& d, const IntSharedArray& r) { - int minimum = Limits::max; - for (int i=0; i& x, const IntDistance& d, - const IntSharedArray& r, bool& changed, bool& realized) { - int count = 0; - int first = -1; - int second = -1; - for (int i=0; i a(x[i]); a() && !supported; ++a) - for (ViewValues b(x[j]); b(); ++b) - if (d(a.val(),b.val()) == 0) { - supported = true; - break; - } - if (supported) { - first = i; second = j; count++; - } - } - if (count == 0) - return ES_FAILED; - if (count == 1) { - // Only this pair can attain zero, so both endpoints need zero support. - Region region; - for (int pass=0; pass<2; pass++) { - IntView a = x[pass == 0 ? first : second]; - IntView b = x[pass == 0 ? second : first]; - int* remove = region.alloc(a.size()); - int nr = 0; - for (ViewValues v(a); v(); ++v) { - bool supported = false; - for (ViewValues w(b); w(); ++w) - if (d(v.val(),w.val()) == 0) { - supported = true; - break; - } - if (!supported) - remove[nr++] = v.val(); - } - if (nr != 0) { - Iter::Values::Array values(remove,static_cast(nr)); - ModEvent me = a.minus_v(home,values,false); - GECODE_ME_CHECK(me); - changed |= me_modified(me); - } - } - } - return ES_OK; - } - - /// Forward-bound actor for one selected-position pair - class Pair : public Propagator { - protected: - IntView x; - IntView y; - IntView z; - IntDistance d; - int r; - Pair(Home home, IntView x0, IntView y0, IntView z0, - const IntDistance& d0, int r0) - : Propagator(home), x(x0), y(y0), z(z0), d(d0), r(r0) { - home.notice(*this,AP_DISPOSE); - x.subscribe(home,*this,PC_INT_DOM); - y.subscribe(home,*this,PC_INT_DOM); - z.subscribe(home,*this,PC_INT_BND); - } - Pair(Space& home, Pair& p) - : Propagator(home,p), d(p.d), r(p.r) { - x.update(home,p.x); y.update(home,p.y); z.update(home,p.z); - } - public: - static ExecStatus post(Home home, IntView x, IntView y, IntView z, - const IntDistance& d, int r) { - if (x.assigned() && y.assigned()) { - int v = d(x.val(),y.val()); - if (v < r) - return ES_FAILED; - GECODE_ME_CHECK(z.lq(home,v)); - } else { - (void) new (home) Pair(home,x,y,z,d,r); - } - return ES_OK; - } - virtual Actor* copy(Space& home) { - return new (home) Pair(home,*this); - } - virtual PropCost cost(const Space&, const ModEventDelta&) const { - return PropCost::quadratic(PropCost::HI,d.size()); - } - virtual void reschedule(Space& home) { - x.reschedule(home,*this,PC_INT_DOM); - y.reschedule(home,*this,PC_INT_DOM); - z.reschedule(home,*this,PC_INT_BND); - } - virtual ExecStatus propagate(Space& home, const ModEventDelta&) { - int threshold = std::max(r,z.min()); - if (x.assigned() && y.assigned()) { - int v = d(x.val(),y.val()); - if (v < threshold) - return ES_FAILED; - GECODE_ME_CHECK(z.lq(home,v)); - return home.ES_SUBSUMED(*this); - } - bool changed = false; - if (x.assigned()) { - GECODE_ES_CHECK(forward(home,x,y,threshold,d,changed)); - } else if (y.assigned()) { - GECODE_ES_CHECK(forward(home,y,x,threshold,d,changed)); - } - PairCache c; - pair_max(x,y,d,c); - if (c.upper < threshold) - return ES_FAILED; - ModEvent me = z.lq(home,c.upper); - GECODE_ME_CHECK(me); - return (changed || me_modified(me) || (z.min() > threshold)) ? ES_NOFIX : ES_FIX; - } - virtual size_t dispose(Space& home) { - home.ignore(*this,AP_DISPOSE); - x.cancel(home,*this,PC_INT_DOM); - y.cancel(home,*this,PC_INT_DOM); - z.cancel(home,*this,PC_INT_BND); - d.~IntDistance(); - (void) Propagator::dispose(home); - return sizeof(*this); - } - }; - - /// Equality finalizer and zero witness for the pairwise organization - class Finalize : public MixNaryOnePropagator { - protected: - IntDistance d; - IntSharedArray r; - Finalize(Home home, ViewArray& x, IntView z, - const IntDistance& d0, const IntSharedArray& r0) - : MixNaryOnePropagator(home,x,z), d(d0), r(r0) { - home.notice(*this,AP_DISPOSE); - } - Finalize(Space& home, Finalize& p) - : MixNaryOnePropagator(home,p), d(p.d), r(p.r) {} - public: - static ExecStatus post(Home home, ViewArray& x, IntView z, - const IntDistance& d, const IntSharedArray& r) { - (void) new (home) Finalize(home,x,z,d,r); - return ES_OK; - } - virtual Actor* copy(Space& home) { - return new (home) Finalize(home,*this); - } - virtual PropCost cost(const Space&, const ModEventDelta&) const { - return PropCost::quadratic(PropCost::HI,x.size()); - } - virtual ExecStatus propagate(Space& home, const ModEventDelta&) { - if (x.assigned()) { - GECODE_ES_CHECK(assigned(home,x,y,d,r)); - return home.ES_SUBSUMED(*this); - } - if (y.max() != 0) - return ES_FIX; - bool changed = false; - bool realized = false; - GECODE_ES_CHECK(zero(home,x,d,r,changed,realized)); - if (realized) - return home.ES_SUBSUMED(*this); - return changed ? ES_NOFIX : ES_FIX; - } - virtual size_t dispose(Space& home) { - home.ignore(*this,AP_DISPOSE); - d.~IntDistance(); r.~IntSharedArray(); - (void) MixNaryOnePropagator::dispose(home); - return sizeof(*this); - } - }; - - /// Single forward-bound actor with domain advisors and pair witnesses - class AdvisorForward : public Propagator { - protected: - class XAdvisor : public Advisor { - public: - int index; - XAdvisor(Space& home, Propagator& p, Council& c, int i) - : Advisor(home,p,c), index(i) {} - XAdvisor(Space& home, XAdvisor& a) - : Advisor(home,a), index(a.index) {} - }; - ViewArray x; - IntView z; - IntDistance d; - IntSharedArray r; - Council council; - PairCache* cache; - bool* dirty; - int last_min; - bool z_shared; - AdvisorForward(Home home, ViewArray& x0, IntView z0, - const IntDistance& d0, const IntSharedArray& r0) - : Propagator(home), x(x0), z(z0), d(d0), r(r0), council(home), - last_min(-1), z_shared(false) { - home.notice(*this,AP_DISPOSE); - Space& s = home; - int np = static_cast(static_cast(x.size())*(x.size()-1)/2); - cache = s.alloc(np); - for (int i=0; i(x.size()); - for (int i=0; i(static_cast(x.size())*(x.size()-1)/2); - cache = home.alloc(np); - std::copy(p.cache,p.cache+np,cache); - dirty = home.alloc(x.size()); - std::copy(p.dirty,p.dirty+x.size(),dirty); - } - public: - static ExecStatus post(Home home, ViewArray& x, IntView z, - const IntDistance& d, const IntSharedArray& r) { - (void) new (home) AdvisorForward(home,x,z,d,r); - return ES_OK; - } - virtual Actor* copy(Space& home) { - return new (home) AdvisorForward(home,*this); - } - virtual PropCost cost(const Space&, const ModEventDelta&) const { - return PropCost::quadratic(PropCost::HI, - static_cast(x.size())+d.size()); - } - virtual void reschedule(Space& home) { - z.reschedule(home,*this,PC_INT_BND); - // Advisors have no reschedule method; ensure a manual reschedule also - // revisits every pair, even if no new domain event has been delivered. - last_min = -1; - } - virtual ExecStatus advise(Space&, Advisor& a, const Delta&) { - dirty[static_cast(a).index] = true; - return ES_NOFIX; - } - virtual ExecStatus propagate(Space& home, const ModEventDelta&) { - for (;;) { - if (x.assigned()) { - GECODE_ES_CHECK(assigned(home,x,z,d,r)); - return home.ES_SUBSUMED(*this); - } - int zmin = z.min(); - bool all_dirty = zmin != last_min; - bool changed = false; - for (int i=0; i a(council); a(); ++a) - x[a.advisor().index].cancel(home,a.advisor()); - council.dispose(home); - z.cancel(home,*this,PC_INT_BND); - home.free(cache,static_cast(static_cast(x.size())*(x.size()-1)/2)); - home.free(dirty,x.size()); - d.~IntDistance(); r.~IntSharedArray(); - (void) Propagator::dispose(home); - return sizeof(*this); - } - }; - - /// Independent matching-based objective upper bound - class Matching : public MixNaryOnePropagator { - protected: - IntDistance d; - Matching(Home home, ViewArray& x, IntView z, - const IntDistance& d0) - : MixNaryOnePropagator(home,x,z), d(d0) { - home.notice(*this,AP_DISPOSE); - } - Matching(Space& home, Matching& p) - : MixNaryOnePropagator(home,p), d(p.d) {} - bool refuted(int* sites, int n, bool* matched, int threshold) const { - if (threshold == 0) - return false; // Repeated sites are permitted at distance zero. - std::fill(matched,matched+n,false); - int edges = 0; - for (int a=0; a& x, IntView z, - const IntDistance& d) { - if (!z.assigned()) - (void) new (home) Matching(home,x,z,d); - return ES_OK; - } - virtual Actor* copy(Space& home) { - return new (home) Matching(home,*this); - } - virtual PropCost cost(const Space&, const ModEventDelta&) const { - return PropCost::cubic(PropCost::HI,d.size()); - } - virtual ExecStatus propagate(Space& home, const ModEventDelta&) { - if (y.assigned()) - return home.ES_SUBSUMED(*this); - Region region; - bool* present = region.alloc(d.size()); - std::fill(present,present+d.size(),false); - for (int i=0; i v(x[i]); v(); ++v) - present[v.val()] = true; - int* sites = region.alloc(d.size()); - int n = 0; - for (int i=0; i(n); - int lo = y.min(); - int hi = y.max(); - if (refuted(sites,n,matched,lo)) - return ES_FAILED; - // A failed certificate at t excludes every objective >= t. Greedy - // certificate sizes themselves need not be monotone, so this search - // can miss tighter bounds but cannot delete a feasible objective. - while (lo < hi) { - int mid = lo+(hi-lo+1)/2; - if (refuted(sites,n,matched,mid)) - hi = mid-1; - else - lo = mid; - } - ModEvent me = y.lq(home,hi); - GECODE_ME_CHECK(me); - if (y.assigned()) - return home.ES_SUBSUMED(*this); - return me_modified(me) ? ES_NOFIX : ES_FIX; - } - virtual size_t dispose(Space& home) { - home.ignore(*this,AP_DISPOSE); - d.~IntDistance(); - (void) MixNaryOnePropagator::dispose(home); - return sizeof(*this); - } - }; - /// Validate the organization and number of positions void check(const IntVarArgs& x, MinDistancePropKind kind) { if (x.size() < 2) @@ -622,4 +140,4 @@ namespace Gecode { } -// STATISTICS: int-prop +// STATISTICS: int-post diff --git a/gecode/int/min-distance.hh b/gecode/int/min-distance.hh new file mode 100644 index 0000000000..bd9a5a8922 --- /dev/null +++ b/gecode/int/min-distance.hh @@ -0,0 +1,222 @@ +/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ +/* + * Main authors: + * Mikael Zayenz Lagerkvist + * + * Copyright: + * Mikael Zayenz Lagerkvist, 2026 + * + * This file is part of Gecode, the generic constraint + * development environment: + * http://www.gecode.dev + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef GECODE_INT_MIN_DISTANCE_HH +#define GECODE_INT_MIN_DISTANCE_HH + +#include + +#include + +/** + * \namespace Gecode::Int::MinDistance + * + * The forward-bound and greedy conflict-matching algorithms follow: + * M. Z. Lagerkvist, Propagation Algorithms for the Minimum-Distance + * Constraint over Selected Points, ModRef 2026. + * https://github.com/zayenz/modref2026-minimum-distance-propagators + * + * \brief Minimum-distance propagators over indexed sites + */ +namespace Gecode { namespace Int { namespace MinDistance { + + /// Pair maximum and its witness + struct PairCache { + int a; ///< Site at the first endpoint + int b; ///< Site at the second endpoint + int upper; ///< Maximum distance between the endpoint domains + }; + + /** + * \brief Forward-bound actor for one selected-position pair + * + * Requires \code #include \endcode + * \ingroup FuncIntProp + */ + class Pair + : public MixTernaryPropagator { + protected: + /// Shared distances + IntDistance d; + /// Inclusive pair requirement + int r; + /// Constructor for posting + Pair(Home home, IntView x0, IntView y0, IntView z0, + const IntDistance& d0, int r0); + /// Constructor for cloning + Pair(Space& home, Pair& p); + public: + /// Post propagator + static ExecStatus post(Home home, IntView x0, IntView x1, IntView x2, + const IntDistance& d, int r); + /// Copy propagator during cloning + virtual Actor* copy(Space& home); + /// Cost function + virtual PropCost cost(const Space&, const ModEventDelta&) const; + /// Perform propagation + virtual ExecStatus propagate(Space& home, const ModEventDelta&); + /// Cancel subscriptions and dispose shared data + virtual size_t dispose(Space& home); + }; + + /** + * \brief Equality finalizer and zero witness for the pairwise organization + * + * Requires \code #include \endcode + * \ingroup FuncIntProp + */ + class Finalize + : public MixNaryOnePropagator { + protected: + /// Shared distances + IntDistance d; + /// Shared pair requirements + IntSharedArray r; + /// Constructor for posting + Finalize(Home home, ViewArray& x, IntView z, + const IntDistance& d0, const IntSharedArray& r0); + /// Constructor for cloning + Finalize(Space& home, Finalize& p); + public: + /// Post propagator + static ExecStatus post(Home home, ViewArray& x, IntView z, + const IntDistance& d, const IntSharedArray& r); + /// Copy propagator during cloning + virtual Actor* copy(Space& home); + /// Cost function + virtual PropCost cost(const Space&, const ModEventDelta&) const; + /// Perform propagation + virtual ExecStatus propagate(Space& home, const ModEventDelta&); + /// Cancel subscriptions and dispose shared data + virtual size_t dispose(Space& home); + }; + + /** + * \brief Single forward-bound actor with domain advisors and pair witnesses + * + * Requires \code #include \endcode + * \ingroup FuncIntProp + */ + class AdvisorForward : public Propagator { + protected: + /// Domain advisor for a selected position + class XAdvisor : public Advisor { + public: + /// Position in the view array + int index; + /// Constructor for creation + XAdvisor(Space& home, Propagator& p, Council& c, int i); + /// Constructor for cloning + XAdvisor(Space& home, XAdvisor& a); + }; + /// Selected sites + ViewArray x; + /// Minimum distance + IntView z; + /// Shared distances + IntDistance d; + /// Shared pair requirements + IntSharedArray r; + /// Domain advisors + Council council; + /// Pair maxima and witnesses + PairCache* cache; + /// Positions changed since the last fixpoint + Support::BitSetBase dirty; + /// Objective lower bound at the last fixpoint + int last_min; + /// Whether the objective shares a selected-site variable + bool z_shared; + /// Constructor for posting + AdvisorForward(Home home, ViewArray& x0, IntView z0, + const IntDistance& d0, const IntSharedArray& r0); + /// Constructor for cloning + AdvisorForward(Space& home, AdvisorForward& p); + public: + /// Post propagator + static ExecStatus post(Home home, ViewArray& x, IntView z, + const IntDistance& d, const IntSharedArray& r); + /// Copy propagator during cloning + virtual Actor* copy(Space& home); + /// Cost function + virtual PropCost cost(const Space&, const ModEventDelta&) const; + /// Reschedule propagation + virtual void reschedule(Space& home); + /// Record a changed selected-site domain + virtual ExecStatus advise(Space&, Advisor& a, const Delta&); + /// Perform propagation + virtual ExecStatus propagate(Space& home, const ModEventDelta&); + /// Cancel subscriptions and dispose stored data + virtual size_t dispose(Space& home); + }; + + /** + * \brief Independent matching-based objective upper bound + * + * Requires \code #include \endcode + * \ingroup FuncIntProp + */ + class Matching + : public MixNaryOnePropagator { + protected: + /// Shared distances + IntDistance d; + /// Constructor for posting + Matching(Home home, ViewArray& x, IntView z, + const IntDistance& d0); + /// Constructor for cloning + Matching(Space& home, Matching& p); + /// Whether a greedy conflict matching refutes the threshold + bool refuted(int* sites, int n, bool* matched, int threshold) const; + public: + /// Post propagator + static ExecStatus post(Home home, ViewArray& x, IntView z, + const IntDistance& d); + /// Copy propagator during cloning + virtual Actor* copy(Space& home); + /// Cost function + virtual PropCost cost(const Space&, const ModEventDelta&) const; + /// Perform propagation + virtual ExecStatus propagate(Space& home, const ModEventDelta&); + /// Cancel subscriptions and dispose shared data + virtual size_t dispose(Space& home); + }; + +}}} + +#include + +#endif + +// STATISTICS: int-prop diff --git a/gecode/int/min-distance/prop.hpp b/gecode/int/min-distance/prop.hpp new file mode 100644 index 0000000000..fa3048bf22 --- /dev/null +++ b/gecode/int/min-distance/prop.hpp @@ -0,0 +1,519 @@ +/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ +/* + * Main authors: + * Mikael Zayenz Lagerkvist + * + * Copyright: + * Mikael Zayenz Lagerkvist, 2026 + * + * This file is part of Gecode, the generic constraint + * development environment: + * http://www.gecode.dev + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +namespace Gecode { namespace Int { namespace MinDistance { + + + /// Inclusive requirement, with an empty matrix denoting all zeroes + forceinline int + requirement(const IntSharedArray& r, int n, int i, int j) { + return !r ? 0 : r[i*n+j]; + } + + /// Prune the partner of an assigned endpoint + inline ExecStatus + forward(Space& home, IntView a, IntView b, int threshold, + const IntDistance& d, bool& changed) { + Region region; + int* remove = region.alloc(b.size()); + int nr = 0; + for (ViewValues v(b); v(); ++v) + if (d(a.val(),v.val()) < threshold) + remove[nr++] = v.val(); + if (nr != 0) { + Iter::Values::Array values(remove,static_cast(nr)); + ModEvent me = b.minus_v(home,values,false); + GECODE_ME_CHECK(me); + changed |= me_modified(me); + } + return ES_OK; + } + + /// Recompute the maximum distance between current domains + inline void + pair_max(IntView x, IntView y, const IntDistance& d, PairCache& c) { + c.upper = -1; + for (ViewValues a(x); a(); ++a) + for (ViewValues b(y); b(); ++b) { + int v = d(a.val(),b.val()); + if (v > c.upper) { + c.a = a.val(); c.b = b.val(); c.upper = v; + } + } + } + + /// Validate and bind a complete assignment + inline ExecStatus + assigned(Space& home, const ViewArray& x, IntView z, + const IntDistance& d, const IntSharedArray& r) { + int minimum = Limits::max; + for (int i=0; i& x, const IntDistance& d, + const IntSharedArray& r, bool& changed, bool& realized) { + int count = 0; + int first = -1; + int second = -1; + for (int i=0; i a(x[i]); a() && !supported; ++a) + for (ViewValues b(x[j]); b(); ++b) + if (d(a.val(),b.val()) == 0) { + supported = true; + break; + } + if (supported) { + first = i; second = j; count++; + } + } + if (count == 0) + return ES_FAILED; + if (count == 1) { + // Only this pair can attain zero, so both endpoints need zero support. + Region region; + for (int pass=0; pass<2; pass++) { + IntView a = x[pass == 0 ? first : second]; + IntView b = x[pass == 0 ? second : first]; + int* remove = region.alloc(a.size()); + int nr = 0; + for (ViewValues v(a); v(); ++v) { + bool supported = false; + for (ViewValues w(b); w(); ++w) + if (d(v.val(),w.val()) == 0) { + supported = true; + break; + } + if (!supported) + remove[nr++] = v.val(); + } + if (nr != 0) { + Iter::Values::Array values(remove,static_cast(nr)); + ModEvent me = a.minus_v(home,values,false); + GECODE_ME_CHECK(me); + changed |= me_modified(me); + } + } + } + return ES_OK; + } + + forceinline + Pair::Pair(Home home, IntView x0, IntView y0, IntView z0, + const IntDistance& d0, int r0) + : MixTernaryPropagator(home,x0,y0,z0), + d(d0), r(r0) { + home.notice(*this,AP_DISPOSE); + } + + forceinline + Pair::Pair(Space& home, Pair& p) + : MixTernaryPropagator(home,p), + d(p.d), r(p.r) {} + + inline ExecStatus + Pair::post(Home home, IntView x0, IntView x1, IntView x2, + const IntDistance& d, int r) { + if (x0.assigned() && x1.assigned()) { + int v = d(x0.val(),x1.val()); + if (v < r) + return ES_FAILED; + GECODE_ME_CHECK(x2.lq(home,v)); + } else { + (void) new (home) Pair(home,x0,x1,x2,d,r); + } + return ES_OK; + } + + inline Actor* + Pair::copy(Space& home) { + return new (home) Pair(home,*this); + } + + inline PropCost + Pair::cost(const Space&, const ModEventDelta&) const { + return PropCost::quadratic(PropCost::HI,d.size()); + } + + inline ExecStatus + Pair::propagate(Space& home, const ModEventDelta&) { + int threshold = std::max(r,x2.min()); + if (x0.assigned() && x1.assigned()) { + int v = d(x0.val(),x1.val()); + if (v < threshold) + return ES_FAILED; + GECODE_ME_CHECK(x2.lq(home,v)); + return home.ES_SUBSUMED(*this); + } + bool changed = false; + if (x0.assigned()) { + GECODE_ES_CHECK(forward(home,x0,x1,threshold,d,changed)); + } else if (x1.assigned()) { + GECODE_ES_CHECK(forward(home,x1,x0,threshold,d,changed)); + } + PairCache c; + pair_max(x0,x1,d,c); + if (c.upper < threshold) + return ES_FAILED; + ModEvent me = x2.lq(home,c.upper); + GECODE_ME_CHECK(me); + return (changed || me_modified(me) || (x2.min() > threshold)) ? ES_NOFIX : ES_FIX; + } + + inline size_t + Pair::dispose(Space& home) { + home.ignore(*this,AP_DISPOSE); + d.~IntDistance(); + (void) MixTernaryPropagator::dispose(home); + return sizeof(*this); + } + + forceinline + Finalize::Finalize(Home home, ViewArray& x, IntView z, + const IntDistance& d0, const IntSharedArray& r0) + : MixNaryOnePropagator(home,x,z), + d(d0), r(r0) { + home.notice(*this,AP_DISPOSE); + } + + forceinline + Finalize::Finalize(Space& home, Finalize& p) + : MixNaryOnePropagator(home,p), + d(p.d), r(p.r) {} + + inline ExecStatus + Finalize::post(Home home, ViewArray& x, IntView z, + const IntDistance& d, const IntSharedArray& r) { + (void) new (home) Finalize(home,x,z,d,r); + return ES_OK; + } + + inline Actor* + Finalize::copy(Space& home) { + return new (home) Finalize(home,*this); + } + + inline PropCost + Finalize::cost(const Space&, const ModEventDelta&) const { + return PropCost::quadratic(PropCost::HI,x.size()); + } + + inline ExecStatus + Finalize::propagate(Space& home, const ModEventDelta&) { + if (x.assigned()) { + GECODE_ES_CHECK(assigned(home,x,y,d,r)); + return home.ES_SUBSUMED(*this); + } + if (y.max() != 0) + return ES_FIX; + bool changed = false; + bool realized = false; + GECODE_ES_CHECK(zero(home,x,d,r,changed,realized)); + if (realized) + return home.ES_SUBSUMED(*this); + return changed ? ES_NOFIX : ES_FIX; + } + + inline size_t + Finalize::dispose(Space& home) { + home.ignore(*this,AP_DISPOSE); + d.~IntDistance(); r.~IntSharedArray(); + (void) MixNaryOnePropagator::dispose(home); + return sizeof(*this); + } + + forceinline + AdvisorForward::XAdvisor::XAdvisor(Space& home, Propagator& p, + Council& c, int i) + : Advisor(home,p,c), index(i) {} + + forceinline + AdvisorForward::XAdvisor::XAdvisor(Space& home, XAdvisor& a) + : Advisor(home,a), index(a.index) {} + + forceinline + AdvisorForward::AdvisorForward(Home home, ViewArray& x0, IntView z0, + const IntDistance& d0, const IntSharedArray& r0) + : Propagator(home), x(x0), z(z0), d(d0), r(r0), council(home), + dirty(static_cast(home),static_cast(x.size()),true), + last_min(-1), z_shared(false) { + home.notice(*this,AP_DISPOSE); + Space& s = home; + int np = static_cast(static_cast(x.size())*(x.size()-1)/2); + cache = s.alloc(np); + for (int i=0; i(static_cast(x.size())*(x.size()-1)/2); + cache = home.alloc(np); + std::copy(p.cache,p.cache+np,cache); + } + + inline ExecStatus + AdvisorForward::post(Home home, ViewArray& x, IntView z, + const IntDistance& d, const IntSharedArray& r) { + (void) new (home) AdvisorForward(home,x,z,d,r); + return ES_OK; + } + + inline Actor* + AdvisorForward::copy(Space& home) { + return new (home) AdvisorForward(home,*this); + } + + inline PropCost + AdvisorForward::cost(const Space&, const ModEventDelta&) const { + return PropCost::quadratic(PropCost::HI, + static_cast(x.size())+d.size()); + } + + forceinline void + AdvisorForward::reschedule(Space& home) { + z.reschedule(home,*this,PC_INT_BND); + // Advisors have no reschedule method; ensure a manual reschedule also + // revisits every pair, even if no new domain event has been delivered. + last_min = -1; + } + + inline ExecStatus + AdvisorForward::advise(Space&, Advisor& a, const Delta&) { + dirty.set(static_cast(a).index); + return ES_NOFIX; + } + + inline ExecStatus + AdvisorForward::propagate(Space& home, const ModEventDelta&) { + for (;;) { + if (x.assigned()) { + GECODE_ES_CHECK(assigned(home,x,z,d,r)); + return home.ES_SUBSUMED(*this); + } + int zmin = z.min(); + bool all_dirty = zmin != last_min; + bool changed = false; + for (int i=0; i a(council); a(); ++a) + x[a.advisor().index].cancel(home,a.advisor()); + council.dispose(home); + z.cancel(home,*this,PC_INT_BND); + int np = static_cast( + static_cast(x.size())*(x.size()-1)/2); + home.free(cache,np); + dirty.dispose(home); + d.~IntDistance(); r.~IntSharedArray(); + (void) Propagator::dispose(home); + return sizeof(*this); + } + + forceinline + Matching::Matching(Home home, ViewArray& x, IntView z, + const IntDistance& d0) + : MixNaryOnePropagator(home,x,z), d(d0) { + home.notice(*this,AP_DISPOSE); + home.notice(*this,AP_WEAKLY); + } + + forceinline + Matching::Matching(Space& home, Matching& p) + : MixNaryOnePropagator(home,p), d(p.d) {} + + inline bool + Matching::refuted(int* sites, int n, bool* matched, int threshold) const { + if (threshold == 0) + return false; // Repeated sites are permitted at distance zero. + std::fill(matched,matched+n,false); + int edges = 0; + for (int a=0; a& x, IntView z, + const IntDistance& d) { + if (!z.assigned()) + (void) new (home) Matching(home,x,z,d); + return ES_OK; + } + + inline Actor* + Matching::copy(Space& home) { + return new (home) Matching(home,*this); + } + + inline PropCost + Matching::cost(const Space&, const ModEventDelta&) const { + return PropCost::cubic(PropCost::HI,d.size()); + } + + inline ExecStatus + Matching::propagate(Space& home, const ModEventDelta&) { + if (y.assigned()) + return home.ES_SUBSUMED(*this); + Region region; + bool* present = region.alloc(d.size()); + std::fill(present,present+d.size(),false); + for (int i=0; i v(x[i]); v(); ++v) + present[v.val()] = true; + int* sites = region.alloc(d.size()); + int n = 0; + for (int i=0; i(n); + int lo = y.min(); + int hi = y.max(); + if (refuted(sites,n,matched,lo)) + return ES_FAILED; + // A failed certificate at t excludes every objective >= t. Greedy + // certificate sizes themselves need not be monotone, so this search + // can miss tighter bounds but cannot delete a feasible objective. + while (lo < hi) { + int mid = lo+(hi-lo+1)/2; + if (refuted(sites,n,matched,mid)) + hi = mid-1; + else + lo = mid; + } + ModEvent me = y.lq(home,hi); + GECODE_ME_CHECK(me); + if (y.assigned()) + return home.ES_SUBSUMED(*this); + return me_modified(me) ? ES_NOFIX : ES_FIX; + } + + inline size_t + Matching::dispose(Space& home) { + home.ignore(*this,AP_DISPOSE); + home.ignore(*this,AP_WEAKLY); + d.~IntDistance(); + (void) MixNaryOnePropagator::dispose(home); + return sizeof(*this); + } + +}}} + +// STATISTICS: int-prop