diff --git a/CMakeLists.txt b/CMakeLists.txt index 12bd087d2a..e9d0600f6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1432,6 +1432,7 @@ if(BUILD_TESTING) 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() diff --git a/Makefile.in b/Makefile.in index 1f041e2e29..b446405125 100755 --- a/Makefile.in +++ b/Makefile.in @@ -1363,7 +1363,7 @@ CHECKTESTS = Branch::Int::Dense::3 \ Set::Wait ifeq "@enable_flatzinc@" "yes" -CHECKTESTS += FlatZinc::blackbox +CHECKTESTS += FlatZinc::Options FlatZinc::blackbox BLACKBOXCHECKENV = \ GECODE_TEST_BLACKBOX_EXEC=$(abspath $(BLACKBOXEXEC)) \ GECODE_TEST_BLACKBOX_DLL=$(abspath $(BLACKBOXDLL)) \ diff --git a/changelog.in b/changelog.in index efbffaeb50..8769e321b4 100755 --- a/changelog.in +++ b/changelog.in @@ -146,6 +146,16 @@ Compute interval medians without overflowing at large positive or negative bounds. Float search over an unbounded FlatZinc variable can otherwise fail to make progress. +[ENTRY] +Module: flatzinc +What: bug +Rank: minor +Issue: 99 +[DESCRIPTION] +Keep an explicitly selected Gist execution mode when FlatZinc statistics are +requested, and report an error instead of silently running in solution mode +when Gist support is unavailable. + [ENTRY] Module: flatzinc What: new diff --git a/gecode/flatzinc.hh b/gecode/flatzinc.hh index 12375e18b2..f4d934d3d1 100755 --- a/gecode/flatzinc.hh +++ b/gecode/flatzinc.hh @@ -329,7 +329,7 @@ namespace Gecode { namespace FlatZinc { if (_time_limit.value()) { _time.value(_time_limit.value()); } - if (_stat.value()) + if (_stat.value() && (_mode.value() == Gecode::SM_SOLUTION)) _mode.value(Gecode::SM_STAT); } diff --git a/gecode/flatzinc/flatzinc.cpp b/gecode/flatzinc/flatzinc.cpp index e66de9c755..e35bd3638c 100644 --- a/gecode/flatzinc/flatzinc.cpp +++ b/gecode/flatzinc/flatzinc.cpp @@ -2039,6 +2039,11 @@ namespace Gecode { namespace FlatZinc { void FlatZincSpace::run(std::ostream& out, const Printer& p, const FlatZincOptions& opt, Support::Timer& t_total) { +#ifndef GECODE_HAS_GIST + if (opt.mode() == SM_GIST) + throw FlatZinc::Error("FlatZinc", + "Gist mode is unavailable in this build"); +#endif switch (_method) { case MIN: case MAX: diff --git a/test/flatzinc.cpp b/test/flatzinc.cpp index 7c6d6724a4..b7c1873b0b 100755 --- a/test/flatzinc.cpp +++ b/test/flatzinc.cpp @@ -65,6 +65,43 @@ namespace Test { namespace FlatZinc { TupleSetAutoRepresentation tuple_set_auto_representation; + /// Verify that statistics do not override an explicit Gist mode. + class GistStatisticsMode : public Base { + private: + static Gecode::ScriptMode mode(std::vector args) { + Gecode::FlatZinc::FlatZincOptions opt("Gecode/FlatZinc"); + std::string cmd("fzn-gecode"); + int argc = static_cast(args.size()) + 1; + std::vector argv(argc); + argv[0] = const_cast(cmd.data()); + for (int i=1; i(args[i-1].data()); + opt.parse(argc,argv.data()); + return opt.mode(); + } + public: + GistStatisticsMode(void) + : Base("FlatZinc::Options::GistStatisticsMode") {} + + virtual bool run(void) { + return + (mode({"-s"}) == Gecode::SM_STAT) && + (mode({"-mode", "gist", "-s"}) == Gecode::SM_GIST) && + (mode({"-s", "-mode", "gist"}) == Gecode::SM_GIST); + } + }; + + GistStatisticsMode gist_statistics_mode; + +#ifndef GECODE_HAS_GIST + /// Verify that unavailable Gist mode is rejected instead of running search. + FlatZincErrorTest gist_unavailable( + "Options::GistUnavailable", + "var 1..1: x :: output_var;\nsolve satisfy;\n", + {"-mode", "gist", "-s"}, + "Gist mode is unavailable in this build"); +#endif + } FlatZincTest::FlatZincTest(const std::string& name, const std::string& source,