1
0

Squashed 'software/gecode/' changes from 313e87646d..70a1cfa856

70a1cfa856 Add reasoning about why a restart happens
5db96c6afc Add initial version of the 'complete' propagator
3410436fc5 Fix include problems on Linux and Windows
0218f3e7be Remove deprecated restart_count from the variables set on restart
7f4a528ced Fix makefile mistake for LastVal constraint
8a39aee00d Initialise LastVal stored as the minimal in the domain
86707c674e Update STATUS to match the new enum
44d672100f Add support for LastVal from FlatZinc
bd8af2e8f6 Subsume after propagation
2f07e027ab Add LastVal propagator
f05cf9daba Output number of copies
707e30c0f0 Update generated parser files
179ee693cc Add restart_number() builtin (to work around the problem that otherwise we can't implement round robin style search)
04a492da17 Fix restart numbers (didn't count incomplete neighbourhoods)
fbaa3529ec Initial implementation of on_restart
6dd39a73dd Update LICENSE
8f5ea30eba Update LICENSE
4236a2e5ec Use std::vector instead of std::array
c53655d685 Dynamically adjust test batch sizes
37248557b6 Require C++11
cc60ea7cde Minor, remove exraneous newline in changelog
74c5f54b9f Make Region pool thread local
6f04ac3514 Use atomic for propagator identifier
2e0c275b07 Add support for parallel testing
3ada422b76 Refactor, extracted run_test function
787c41b8c4 Refactor, move data and logic into Options
120fc512a7 Refactor, extract run_tests function
85dd87a4af Refactoring: Thread rand through calls in test
cece9da4ef Refactor Assignments operator() to has_more
564410e4ee Refactor Assignment operator++ to next()
e1c84af894 Separate test filtering from running
8558856298 Remove empty statement warnings
a9d8cb64fa Fix compilation errors for CPProfiler support
9ec81a69b2 Add RestartStop
REVERT: 313e87646d Fix include problems on Linux and Windows
REVERT: 358b8ca63b Remove deprecated restart_count from the variables set on restart
REVERT: 83508d5de2 Fix makefile mistake for LastVal constraint
REVERT: 530bbaf107 Initialise LastVal stored as the minimal in the domain
REVERT: 96ba0d3d7e Update STATUS to match the new enum
REVERT: 7d772297f9 Add support for LastVal from FlatZinc
REVERT: 98b0162d75 Subsume after propagation
REVERT: 5cd4552144 Add LastVal propagator
REVERT: 9b80e644b7 Output number of copies
REVERT: aaa5301366 Update generated parser files
REVERT: 6ff4efe6a4 Add restart_number() builtin (to work around the problem that otherwise we can't implement round robin style search)
REVERT: 8bcbec5d6e Fix restart numbers (didn't count incomplete neighbourhoods)
REVERT: 3f63e743b2 Initial implementation of on_restart
REVERT: b6ffa462d1 Update LICENSE
REVERT: ad0621c26c Update LICENSE
REVERT: 93caa97684 Use std::vector instead of std::array
REVERT: 32d6399b35 Dynamically adjust test batch sizes
REVERT: e7f00e9977 Require C++11
REVERT: a5ba8e4282 Minor, remove exraneous newline in changelog
REVERT: b24831354d Make Region pool thread local
REVERT: b1a109ac2e Use atomic for propagator identifier
REVERT: 3d77aaad71 Add support for parallel testing
REVERT: b1b9526049 Refactor, extracted run_test function
REVERT: 85b8a57f65 Refactor, move data and logic into Options
REVERT: d2c1961437 Refactor, extract run_tests function
REVERT: 0236327c75 Refactoring: Thread rand through calls in test
REVERT: ba81289b02 Refactor Assignments operator() to has_more
REVERT: 038a554bd8 Refactor Assignment operator++ to next()
REVERT: f34f125131 Separate test filtering from running
REVERT: cec6336ede Remove empty statement warnings
REVERT: d63e1fc042 Fix compilation errors for CPProfiler support

git-subtree-dir: software/gecode
git-subtree-split: 70a1cfa856d138b0845d2681c46ca16f8507aebf
This commit is contained in:
Jip J. Dekker 2021-07-11 16:26:15 +10:00
parent 1d9faf38de
commit 6719176975
22 changed files with 684 additions and 379 deletions

View File

@ -817,11 +817,11 @@ endif
# FLATZINC
#
FLATZINCSRC0 = flatzinc.cpp registry.cpp branch.cpp lastval.cpp
FLATZINCSRC0 = flatzinc.cpp registry.cpp branch.cpp lastval.cpp complete.cpp
FLATZINC_GENSRC0 = parser.tab.cpp lexer.yy.cpp
FLATZINCHDR0 = ast.hh conexpr.hh option.hh parser.hh \
plugin.hh registry.hh symboltable.hh varspec.hh \
branch.hh branch.hpp lastval.hh
branch.hh branch.hpp lastval.hh complete.hh
FLATZINCSRC = $(FLATZINCSRC0:%=gecode/flatzinc/%)
FLATZINC_GENSRC = $(FLATZINC_GENSRC0:%=gecode/flatzinc/%)

View File

@ -69,6 +69,16 @@ Date: 2020-??-??
[DESCRIPTION]
Let's see.
[ENTRY]
Module: search
What: new
Rank: minor
Thanks: Jip J. Dekker
[DESCRIPTION]
Add RestartStop class to enforce a limit on the amount of restarts conducted
in a search. RestartStop is included in CombinedStop and accessible from the
FlatZinc interface through the --restart-limit flag.
[RELEASE]
Version: 6.3.0
Date: 2020-??-??

View File

@ -440,6 +440,8 @@ namespace Gecode {
Driver::StringOption _restart; ///< Restart method option
Driver::DoubleOption _r_base; ///< Restart base
Driver::UnsignedIntOption _r_scale; ///< Restart scale factor
Driver::UnsignedLongLongIntOption
_r_limit; ///< Cutoff for number of restarts
Driver::BoolOption _nogoods; ///< Whether to use no-goods
Driver::UnsignedIntOption _nogoods_limit; ///< Limit for no-good extraction
Driver::DoubleOption _relax; ///< Probability to relax variable
@ -591,6 +593,11 @@ namespace Gecode {
/// Return restart scale factor
unsigned int restart_scale(void) const;
/// Set default restart cutoff
void restart_limit(unsigned long long int n);
/// Return restart cutoff
unsigned long long int restart_limit(void) const;
/// Set default nogoods posting behavior
void nogoods(bool b);
/// Return whether nogoods are used

View File

@ -637,6 +637,7 @@ namespace Gecode {
Search::Config::base),
_r_scale("restart-scale","scale factor for restart sequence",
Search::Config::slice),
_r_limit("restart-limit","restart cutoff (0 = none, solution mode)"),
_nogoods("nogoods","whether to use no-goods from restarts",false),
_nogoods_limit("nogoods-limit","depth limit for no-good extraction",
Search::Config::nogoods_limit),
@ -679,7 +680,7 @@ namespace Gecode {
add(_d_l);
add(_node); add(_fail); add(_time); add(_interrupt);
add(_assets); add(_slice);
add(_restart); add(_r_base); add(_r_scale);
add(_restart); add(_r_base); add(_r_scale); add(_r_limit);
add(_nogoods); add(_nogoods_limit);
add(_relax);
add(_mode); add(_iterations); add(_samples); add(_print_last);

View File

@ -425,6 +425,15 @@ namespace Gecode {
return _r_scale.value();
}
inline void
Options::restart_limit(unsigned long long int n) {
_r_limit.value(n);
}
inline unsigned long long int
Options::restart_limit(void) const {
return _r_limit.value();
}
inline void
Options::nogoods(bool b) {
_nogoods.value(b);

View File

@ -52,15 +52,18 @@ namespace Gecode { namespace Driver {
Search::NodeStop* ns; ///< Used node stop object
Search::FailStop* fs; ///< Used fail stop object
Search::TimeStop* ts; ///< Used time stop object
Search::RestartStop* rs; ///< Used restart stop object
GECODE_DRIVER_EXPORT
static bool sigint; ///< Whether search was interrupted using Ctrl-C
/// Initialize stop object
CombinedStop(unsigned long long int node,
unsigned long long int fail,
double time)
double time,
unsigned long long int restart)
: ns((node > 0ULL) ? new Search::NodeStop(node) : nullptr),
fs((fail > 0ULL) ? new Search::FailStop(fail) : nullptr),
ts((time > 0.0) ? new Search::TimeStop(time) : nullptr) {
ts((time > 0.0) ? new Search::TimeStop(time) : nullptr),
rs((restart > 0.0) ? new Search::RestartStop(restart) : nullptr) {
sigint = false;
}
public:
@ -69,7 +72,8 @@ namespace Gecode { namespace Driver {
SR_NODE = 1 << 0, ///< Node limit reached
SR_FAIL = 1 << 1, ///< Fail limit reached
SR_TIME = 1 << 2, ///< Time limit reached
SR_INT = 1 << 3 ///< Interrupted by user
SR_RESTART = 1 << 3, ///< Time limit reached
SR_INT = 1 << 4 ///< Interrupted by user
};
/// Test whether search must be stopped
virtual bool stop(const Search::Statistics& s, const Search::Options& o) {
@ -77,7 +81,8 @@ namespace Gecode { namespace Driver {
sigint ||
((ns != nullptr) && ns->stop(s,o)) ||
((fs != nullptr) && fs->stop(s,o)) ||
((ts != nullptr) && ts->stop(s,o));
((ts != nullptr) && ts->stop(s,o)) ||
((rs != nullptr) && rs->stop(s,o));
}
/// Report reason why search has been stopped
int reason(const Search::Statistics& s, const Search::Options& o) {
@ -85,6 +90,7 @@ namespace Gecode { namespace Driver {
(((ns != nullptr) && ns->stop(s,o)) ? SR_NODE : 0) |
(((fs != nullptr) && fs->stop(s,o)) ? SR_FAIL : 0) |
(((ts != nullptr) && ts->stop(s,o)) ? SR_TIME : 0) |
(((rs != nullptr) && rs->stop(s,o)) ? SR_RESTART : 0) |
(sigint ? SR_INT : 0);
}
/// Create appropriate stop-object
@ -92,11 +98,12 @@ namespace Gecode { namespace Driver {
create(unsigned long long int node,
unsigned long long int fail,
double time,
unsigned long long int restart,
bool intr) {
if (!intr && (node == 0ULL) && (fail == 0ULL) && (time == 0.0))
if (!intr && (node == 0ULL) && (fail == 0ULL) && (time == 0.0) && (restart == 0ULL))
return nullptr;
else
return new CombinedStop(node,fail,time);
return new CombinedStop(node,fail,time,restart);
}
#ifdef GECODE_THREADS_WINDOWS
/// Handler for catching Ctrl-C
@ -128,7 +135,7 @@ namespace Gecode { namespace Driver {
}
/// Destructor
~CombinedStop(void) {
delete ns; delete fs; delete ts;
delete ns; delete fs; delete ts; delete rs;
}
};
@ -378,7 +385,7 @@ namespace Gecode { namespace Driver {
so.d_l = o.d_l();
so.assets = o.assets();
so.slice = o.slice();
so.stop = CombinedStop::create(o.node(),o.fail(), o.time(),
so.stop = CombinedStop::create(o.node(),o.fail(), o.time(), o.restart_limit(),
o.interrupt());
so.cutoff = createCutoff(o);
so.clone = false;
@ -430,6 +437,8 @@ namespace Gecode { namespace Driver {
l_out << "fail ";
if (r & CombinedStop::SR_TIME)
l_out << "time ";
if (r & CombinedStop::SR_RESTART)
l_out << "restart ";
l_out << "limit reached" << endl << endl;
}
}
@ -479,7 +488,7 @@ namespace Gecode { namespace Driver {
so.c_d = o.c_d();
so.a_d = o.a_d();
so.d_l = o.d_l();
so.stop = CombinedStop::create(o.node(),o.fail(), o.time(),
so.stop = CombinedStop::create(o.node(),o.fail(), o.time(), o.restart_limit(),
o.interrupt());
so.cutoff = createCutoff(o);
so.nogoods_limit = o.nogoods() ? o.nogoods_limit() : 0U;
@ -541,7 +550,7 @@ namespace Gecode { namespace Driver {
sok.c_d = o.c_d();
sok.a_d = o.a_d();
sok.d_l = o.d_l();
sok.stop = CombinedStop::create(o.node(),o.fail(), o.time(),
sok.stop = CombinedStop::create(o.node(),o.fail(), o.time(), o.restart_limit(),
false);
sok.cutoff = createCutoff(o);
sok.nogoods_limit = o.nogoods() ? o.nogoods_limit() : 0U;

View File

@ -244,6 +244,7 @@ namespace Gecode { namespace FlatZinc {
Gecode::Driver::StringOption _restart; ///< Restart method option
Gecode::Driver::DoubleOption _r_base; ///< Restart base
Gecode::Driver::UnsignedIntOption _r_scale; ///< Restart scale factor
Gecode::Driver::UnsignedLongLongIntOption _r_limit; ///< Cutoff for number of restarts
Gecode::Driver::BoolOption _nogoods; ///< Whether to use no-goods
Gecode::Driver::UnsignedIntOption _nogoods_limit; ///< Depth limit for extracting no-goods
Gecode::Driver::BoolOption _interrupt; ///< Whether to catch SIGINT
@ -281,6 +282,7 @@ namespace Gecode { namespace FlatZinc {
_restart("restart","restart sequence type",RM_NONE),
_r_base("restart-base","base for geometric restart sequence",1.5),
_r_scale("restart-scale","scale factor for restart sequence",250),
_r_limit("restart-limit","restart cutoff (0 = none, solution mode)"),
_nogoods("nogoods","whether to use no-goods from restarts",false),
_nogoods_limit("nogoods-limit","depth limit for no-good extraction",
Search::Config::nogoods_limit),
@ -312,7 +314,7 @@ namespace Gecode { namespace FlatZinc {
add(_node); add(_fail); add(_time); add(_time_limit); add(_interrupt);
add(_seed);
add(_step);
add(_restart); add(_r_base); add(_r_scale);
add(_restart); add(_r_base); add(_r_scale); add(_r_limit);
add(_nogoods); add(_nogoods_limit);
add(_mode); add(_stat);
add(_output);
@ -368,6 +370,7 @@ namespace Gecode { namespace FlatZinc {
void restart_base(double d) { _r_base.value(d); }
unsigned int restart_scale(void) const { return _r_scale.value(); }
void restart_scale(int i) { _r_scale.value(i); }
unsigned long long int restart_limit(void) const { return _r_limit.value(); }
bool nogoods(void) const { return _nogoods.value(); }
unsigned int nogoods_limit(void) const { return _nogoods_limit.value(); }
bool interrupt(void) const { return _interrupt.value(); }
@ -482,6 +485,9 @@ namespace Gecode { namespace FlatZinc {
/// The integer variables used in LNS
Gecode::IntVarArray iv_lns;
/// Complete() variable
Gecode::BoolVarArray restart_complete;
std::shared_ptr<bool> complete_marker;
/// Status() variable
Gecode::IntVarArray restart_status;
/// int_uniform arguments

View File

@ -0,0 +1,70 @@
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Jip J. Dekker <jip.dekker@monash.edu>
*
* Copyright:
* Jip J. Dekker, 2018
*
* 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 "complete.hh"
namespace Gecode { namespace FlatZinc {
Complete::Complete(Space &home, Complete &p)
: UnaryPropagator<BoolView, PC_BOOL_VAL>(home,p), c(p.c) {}
Complete::Complete(Home home, BoolView x0, std::shared_ptr<bool> c)
: c(c), UnaryPropagator<BoolView, PC_BOOL_VAL>(home, x0) {}
Actor* Complete::copy(Space &home) {
return new (home) Complete(home,*this);
}
PropCost Complete::cost(const Space &home, const ModEventDelta &med) const {
return PropCost::record();
}
ExecStatus Complete::propagate(Space &home, const ModEventDelta &med) {
assert(x0.assigned());
(*c) = x0.val();
return ES_FAILED;
}
ExecStatus Complete::post(Home home, BoolView x0, std::shared_ptr<bool> c) {
assert(c != nullptr);
if (x0.assigned()) {
(*c) = x0.val();
} else {
(void) new (home) Complete(home, x0, c);
}
return ES_OK;
}
}}

View File

@ -0,0 +1,65 @@
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Jip J. Dekker <jip.dekker@monash.edu>
*
* Copyright:
* Jip J. Dekker, 2018
*
* 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 __FLATZINC_COMPLETE_HH__
#define __FLATZINC_COMPLETE_HH__
#include <gecode/int.hh>
#include <memory>
using namespace Gecode::Int;
namespace Gecode { namespace FlatZinc {
class Complete : public UnaryPropagator<BoolView, PC_BOOL_VAL> {
protected:
using UnaryPropagator<BoolView,PC_BOOL_VAL>::x0;
std::shared_ptr<bool> c;
/// Constructor for cloning \a p
Complete(Space& home, Complete& p);
/// Constructor for posting
Complete(Home home, BoolView x0, std::shared_ptr<bool> c);
public:
/// Copy propagator during cloning
virtual Actor* copy(Space& home);
/// Cost function (defined as TODO)
virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
/// Perform propagation
virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
static ExecStatus post(Home home, BoolView x0, std::shared_ptr<bool> c);
};
}}
#endif //__FLATZINC_COMPLETE_HH__

View File

@ -790,6 +790,7 @@ namespace Gecode { namespace FlatZinc {
iv_lns.update(*this, f.iv_lns);
intVarCount = f.intVarCount;
restart_complete.update(*this, f.restart_complete);
restart_status.update(*this, f.restart_status);
int_uniform_var.update(*this, f.int_uniform_var);
int_uniform_lb = f.int_uniform_lb;
@ -1847,7 +1848,7 @@ namespace Gecode { namespace FlatZinc {
n_p = PropagatorGroup::all.size(*this);
}
Search::Options o;
o.stop = Driver::CombinedStop::create(opt.node(), opt.fail(), opt.time(),
o.stop = Driver::CombinedStop::create(opt.node(), opt.fail(), opt.time(), opt.restart_limit(),
true);
o.c_d = opt.c_d();
o.a_d = opt.a_d();
@ -2012,16 +2013,37 @@ namespace Gecode { namespace FlatZinc {
bool
FlatZincSpace::slave(const MetaInfo& mi) {
if (mi.type() == MetaInfo::RESTART) {
if (restart_complete.size() > 0) {
assert(restart_complete.size() == 1);
assert(complete_marker != nullptr);
if (*complete_marker) {
// Fail the space
this->fail();
// Return true to signal we are in the global search space
return true;
}
}
bool ret = false;
if (restart_status.size() > 0) {
assert(restart_status.size() == 1);
if (!mi.last()) {
rel(*this, restart_status[0], IRT_EQ, 1); // 1: START
} else if (mi.solution() > 0) {
rel(*this, restart_status[0], IRT_EQ, 4); // 4: SAT
} else {
rel(*this, restart_status[0], IRT_EQ, 2); // 2: UNKNOWN
}
switch(mi.reason()) {
case MetaInfo::RR_INIT:
assert(!mi.last());
rel(*this, restart_status[0], IRT_EQ, 1); // 1: START
break;
case MetaInfo::RR_SOL:
assert(mi.solution() > 0);
rel(*this, restart_status[0], IRT_EQ, 4); // 4: SAT
break;
case MetaInfo::RR_CMPL:
rel(*this, restart_status[0], IRT_EQ, 3); // 3: UNSAT
break;
default:
assert(mi.reason() == MetaInfo::RR_LIM);
rel(*this, restart_status[0], IRT_EQ, 2); // 2: UNKNOWN
break;
}
restart_status = IntVarArray(*this, 0);
ret = true;
}

View File

@ -597,7 +597,7 @@ static const flex_int32_t yy_rule_can_match_eol[57] =
#define yymore() yymore_used_but_not_detected
#define YY_MORE_ADJ 0
#define YY_RESTORE_YY_MORE_OFFSET
#line 1 "../gecode/flatzinc/lexer.lxx"
#line 1 "gecode/flatzinc/lexer.lxx"
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
@ -630,7 +630,7 @@ static const flex_int32_t yy_rule_can_match_eol[57] =
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#line 40 "../gecode/flatzinc/lexer.lxx"
#line 40 "gecode/flatzinc/lexer.lxx"
#if defined __GNUC__
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-parameter"
@ -939,7 +939,7 @@ YY_DECL
}
{
#line 75 "../gecode/flatzinc/lexer.lxx"
#line 75 "gecode/flatzinc/lexer.lxx"
#line 945 "gecode/flatzinc/lexer.yy.cpp"
@ -1014,32 +1014,32 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
/* rule 1 can match eol */
YY_RULE_SETUP
#line 77 "../gecode/flatzinc/lexer.lxx"
#line 77 "gecode/flatzinc/lexer.lxx"
{ /*yylineno++;*/ /* ignore EOL */ }
YY_BREAK
case 2:
YY_RULE_SETUP
#line 78 "../gecode/flatzinc/lexer.lxx"
#line 78 "gecode/flatzinc/lexer.lxx"
{ /* ignore whitespace */ }
YY_BREAK
case 3:
YY_RULE_SETUP
#line 79 "../gecode/flatzinc/lexer.lxx"
#line 79 "gecode/flatzinc/lexer.lxx"
{ /* ignore comments */ }
YY_BREAK
case 4:
YY_RULE_SETUP
#line 81 "../gecode/flatzinc/lexer.lxx"
#line 81 "gecode/flatzinc/lexer.lxx"
{ yylval->iValue = 1; return FZ_BOOL_LIT; }
YY_BREAK
case 5:
YY_RULE_SETUP
#line 82 "../gecode/flatzinc/lexer.lxx"
#line 82 "gecode/flatzinc/lexer.lxx"
{ yylval->iValue = 0; return FZ_BOOL_LIT; }
YY_BREAK
case 6:
YY_RULE_SETUP
#line 83 "../gecode/flatzinc/lexer.lxx"
#line 83 "gecode/flatzinc/lexer.lxx"
{ if (parseInt(yytext,yylval->iValue))
return FZ_INT_LIT;
else
@ -1052,7 +1052,7 @@ YY_RULE_SETUP
YY_BREAK
case 7:
YY_RULE_SETUP
#line 92 "../gecode/flatzinc/lexer.lxx"
#line 92 "gecode/flatzinc/lexer.lxx"
{ if (parseInt(yytext,yylval->iValue))
return FZ_INT_LIT;
else
@ -1065,7 +1065,7 @@ YY_RULE_SETUP
YY_BREAK
case 8:
YY_RULE_SETUP
#line 101 "../gecode/flatzinc/lexer.lxx"
#line 101 "gecode/flatzinc/lexer.lxx"
{ if (parseInt(yytext,yylval->iValue))
return FZ_INT_LIT;
else
@ -1078,235 +1078,235 @@ YY_RULE_SETUP
YY_BREAK
case 9:
YY_RULE_SETUP
#line 110 "../gecode/flatzinc/lexer.lxx"
#line 110 "gecode/flatzinc/lexer.lxx"
{ yylval->dValue = strtod(yytext,NULL);
return FZ_FLOAT_LIT; }
YY_BREAK
case 10:
YY_RULE_SETUP
#line 112 "../gecode/flatzinc/lexer.lxx"
#line 112 "gecode/flatzinc/lexer.lxx"
{ yylval->dValue = strtod(yytext,NULL);
return FZ_FLOAT_LIT; }
YY_BREAK
case 11:
YY_RULE_SETUP
#line 114 "../gecode/flatzinc/lexer.lxx"
#line 114 "gecode/flatzinc/lexer.lxx"
{ yylval->dValue = strtod(yytext,NULL);
return FZ_FLOAT_LIT; }
YY_BREAK
case 12:
YY_RULE_SETUP
#line 116 "../gecode/flatzinc/lexer.lxx"
#line 116 "gecode/flatzinc/lexer.lxx"
{ return *yytext; }
YY_BREAK
case 13:
YY_RULE_SETUP
#line 117 "../gecode/flatzinc/lexer.lxx"
#line 117 "gecode/flatzinc/lexer.lxx"
{ return FZ_DOTDOT; }
YY_BREAK
case 14:
YY_RULE_SETUP
#line 118 "../gecode/flatzinc/lexer.lxx"
#line 118 "gecode/flatzinc/lexer.lxx"
{ return FZ_COLONCOLON; }
YY_BREAK
case 15:
YY_RULE_SETUP
#line 119 "../gecode/flatzinc/lexer.lxx"
#line 119 "gecode/flatzinc/lexer.lxx"
{ return FZ_ANNOTATION; }
YY_BREAK
case 16:
YY_RULE_SETUP
#line 120 "../gecode/flatzinc/lexer.lxx"
#line 120 "gecode/flatzinc/lexer.lxx"
{ return FZ_ANY; }
YY_BREAK
case 17:
YY_RULE_SETUP
#line 121 "../gecode/flatzinc/lexer.lxx"
#line 121 "gecode/flatzinc/lexer.lxx"
{ return FZ_ARRAY; }
YY_BREAK
case 18:
YY_RULE_SETUP
#line 122 "../gecode/flatzinc/lexer.lxx"
#line 122 "gecode/flatzinc/lexer.lxx"
{ return FZ_BOOL; }
YY_BREAK
case 19:
YY_RULE_SETUP
#line 123 "../gecode/flatzinc/lexer.lxx"
#line 123 "gecode/flatzinc/lexer.lxx"
{ return FZ_CASE; }
YY_BREAK
case 20:
YY_RULE_SETUP
#line 124 "../gecode/flatzinc/lexer.lxx"
#line 124 "gecode/flatzinc/lexer.lxx"
{ return FZ_CONSTRAINT; }
YY_BREAK
case 21:
YY_RULE_SETUP
#line 125 "../gecode/flatzinc/lexer.lxx"
#line 125 "gecode/flatzinc/lexer.lxx"
{ return FZ_DEFAULT; }
YY_BREAK
case 22:
YY_RULE_SETUP
#line 126 "../gecode/flatzinc/lexer.lxx"
#line 126 "gecode/flatzinc/lexer.lxx"
{ return FZ_ELSE; }
YY_BREAK
case 23:
YY_RULE_SETUP
#line 127 "../gecode/flatzinc/lexer.lxx"
#line 127 "gecode/flatzinc/lexer.lxx"
{ return FZ_ELSEIF; }
YY_BREAK
case 24:
YY_RULE_SETUP
#line 128 "../gecode/flatzinc/lexer.lxx"
#line 128 "gecode/flatzinc/lexer.lxx"
{ return FZ_ENDIF; }
YY_BREAK
case 25:
YY_RULE_SETUP
#line 129 "../gecode/flatzinc/lexer.lxx"
#line 129 "gecode/flatzinc/lexer.lxx"
{ return FZ_ENUM; }
YY_BREAK
case 26:
YY_RULE_SETUP
#line 130 "../gecode/flatzinc/lexer.lxx"
#line 130 "gecode/flatzinc/lexer.lxx"
{ return FZ_FLOAT; }
YY_BREAK
case 27:
YY_RULE_SETUP
#line 131 "../gecode/flatzinc/lexer.lxx"
#line 131 "gecode/flatzinc/lexer.lxx"
{ return FZ_FUNCTION; }
YY_BREAK
case 28:
YY_RULE_SETUP
#line 132 "../gecode/flatzinc/lexer.lxx"
#line 132 "gecode/flatzinc/lexer.lxx"
{ return FZ_IF; }
YY_BREAK
case 29:
YY_RULE_SETUP
#line 133 "../gecode/flatzinc/lexer.lxx"
#line 133 "gecode/flatzinc/lexer.lxx"
{ return FZ_INCLUDE; }
YY_BREAK
case 30:
YY_RULE_SETUP
#line 134 "../gecode/flatzinc/lexer.lxx"
#line 134 "gecode/flatzinc/lexer.lxx"
{ return FZ_INT; }
YY_BREAK
case 31:
YY_RULE_SETUP
#line 135 "../gecode/flatzinc/lexer.lxx"
#line 135 "gecode/flatzinc/lexer.lxx"
{ return FZ_LET; }
YY_BREAK
case 32:
YY_RULE_SETUP
#line 136 "../gecode/flatzinc/lexer.lxx"
#line 136 "gecode/flatzinc/lexer.lxx"
{ yylval->bValue = false; return FZ_MAXIMIZE; }
YY_BREAK
case 33:
YY_RULE_SETUP
#line 137 "../gecode/flatzinc/lexer.lxx"
#line 137 "gecode/flatzinc/lexer.lxx"
{ yylval->bValue = true; return FZ_MINIMIZE; }
YY_BREAK
case 34:
YY_RULE_SETUP
#line 138 "../gecode/flatzinc/lexer.lxx"
#line 138 "gecode/flatzinc/lexer.lxx"
{ return FZ_OF; }
YY_BREAK
case 35:
YY_RULE_SETUP
#line 139 "../gecode/flatzinc/lexer.lxx"
#line 139 "gecode/flatzinc/lexer.lxx"
{ return FZ_SATISFY; }
YY_BREAK
case 36:
YY_RULE_SETUP
#line 140 "../gecode/flatzinc/lexer.lxx"
#line 140 "gecode/flatzinc/lexer.lxx"
{ return FZ_OUTPUT; }
YY_BREAK
case 37:
YY_RULE_SETUP
#line 141 "../gecode/flatzinc/lexer.lxx"
#line 141 "gecode/flatzinc/lexer.lxx"
{ yylval->bValue = false; return FZ_PAR; }
YY_BREAK
case 38:
YY_RULE_SETUP
#line 142 "../gecode/flatzinc/lexer.lxx"
#line 142 "gecode/flatzinc/lexer.lxx"
{ return FZ_PREDICATE; }
YY_BREAK
case 39:
YY_RULE_SETUP
#line 143 "../gecode/flatzinc/lexer.lxx"
#line 143 "gecode/flatzinc/lexer.lxx"
{ return FZ_RECORD; }
YY_BREAK
case 40:
YY_RULE_SETUP
#line 144 "../gecode/flatzinc/lexer.lxx"
#line 144 "gecode/flatzinc/lexer.lxx"
{ return FZ_SET; }
YY_BREAK
case 41:
YY_RULE_SETUP
#line 145 "../gecode/flatzinc/lexer.lxx"
#line 145 "gecode/flatzinc/lexer.lxx"
{ return FZ_SHOWCOND; }
YY_BREAK
case 42:
YY_RULE_SETUP
#line 146 "../gecode/flatzinc/lexer.lxx"
#line 146 "gecode/flatzinc/lexer.lxx"
{ return FZ_SHOW; }
YY_BREAK
case 43:
YY_RULE_SETUP
#line 147 "../gecode/flatzinc/lexer.lxx"
#line 147 "gecode/flatzinc/lexer.lxx"
{ return FZ_SOLVE; }
YY_BREAK
case 44:
YY_RULE_SETUP
#line 148 "../gecode/flatzinc/lexer.lxx"
#line 148 "gecode/flatzinc/lexer.lxx"
{ return FZ_STRING; }
YY_BREAK
case 45:
YY_RULE_SETUP
#line 149 "../gecode/flatzinc/lexer.lxx"
#line 149 "gecode/flatzinc/lexer.lxx"
{ return FZ_TEST; }
YY_BREAK
case 46:
YY_RULE_SETUP
#line 150 "../gecode/flatzinc/lexer.lxx"
#line 150 "gecode/flatzinc/lexer.lxx"
{ return FZ_THEN; }
YY_BREAK
case 47:
YY_RULE_SETUP
#line 151 "../gecode/flatzinc/lexer.lxx"
#line 151 "gecode/flatzinc/lexer.lxx"
{ return FZ_TUPLE; }
YY_BREAK
case 48:
YY_RULE_SETUP
#line 152 "../gecode/flatzinc/lexer.lxx"
#line 152 "gecode/flatzinc/lexer.lxx"
{ return FZ_TYPE; }
YY_BREAK
case 49:
YY_RULE_SETUP
#line 153 "../gecode/flatzinc/lexer.lxx"
#line 153 "gecode/flatzinc/lexer.lxx"
{ yylval->bValue = true; return FZ_VAR; }
YY_BREAK
case 50:
YY_RULE_SETUP
#line 154 "../gecode/flatzinc/lexer.lxx"
#line 154 "gecode/flatzinc/lexer.lxx"
{ return FZ_VARIANT_RECORD; }
YY_BREAK
case 51:
YY_RULE_SETUP
#line 155 "../gecode/flatzinc/lexer.lxx"
#line 155 "gecode/flatzinc/lexer.lxx"
{ return FZ_WHERE; }
YY_BREAK
case 52:
YY_RULE_SETUP
#line 156 "../gecode/flatzinc/lexer.lxx"
#line 156 "gecode/flatzinc/lexer.lxx"
{ yylval->sValue = strdup(yytext); return FZ_ID; }
YY_BREAK
case 53:
YY_RULE_SETUP
#line 157 "../gecode/flatzinc/lexer.lxx"
#line 157 "gecode/flatzinc/lexer.lxx"
{ yylval->sValue = strdup(yytext); return FZ_U_ID; }
YY_BREAK
case 54:
YY_RULE_SETUP
#line 158 "../gecode/flatzinc/lexer.lxx"
#line 158 "gecode/flatzinc/lexer.lxx"
{
yylval->sValue = strdup(yytext+1);
yylval->sValue[strlen(yytext)-2] = 0;
@ -1314,12 +1314,12 @@ YY_RULE_SETUP
YY_BREAK
case 55:
YY_RULE_SETUP
#line 162 "../gecode/flatzinc/lexer.lxx"
#line 162 "gecode/flatzinc/lexer.lxx"
{ yyerror("Unknown character"); }
YY_BREAK
case 56:
YY_RULE_SETUP
#line 163 "../gecode/flatzinc/lexer.lxx"
#line 163 "gecode/flatzinc/lexer.lxx"
ECHO;
YY_BREAK
#line 1325 "gecode/flatzinc/lexer.yy.cpp"
@ -2514,7 +2514,7 @@ void yyfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
#line 163 "../gecode/flatzinc/lexer.lxx"
#line 163 "gecode/flatzinc/lexer.lxx"
int yy_input_proc(char* buf, int size, yyscan_t yyscanner) {
Gecode::FlatZinc::ParserState* parm =

View File

@ -213,6 +213,7 @@ namespace Gecode { namespace FlatZinc {
std::vector<ConExpr*> domainConstraints;
int status_idx = -1;
int complete_idx = -1;
std::vector<std::array<int, 3>> int_uniform;
std::vector<std::array<int, 2>> int_sol;
std::vector<std::array<int, 2>> int_lastval;

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.2. */
/* A Bison parser, made by GNU Bison 3.7.6. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
@ -16,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -107,7 +107,7 @@ extern int yydebug;
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
#line 502 "../gecode/flatzinc/parser.yxx"
#line 509 "gecode/flatzinc/parser.yxx"
int iValue; char* sValue; bool bValue; double dValue;
std::vector<int>* setValue;
Gecode::FlatZinc::AST::SetLit* setLit;

View File

@ -40,6 +40,7 @@
#include <gecode/flatzinc.hh>
#include <gecode/flatzinc/parser.hh>
#include <gecode/flatzinc/lastval.hh>
#include <gecode/flatzinc/complete.hh>
#include <iostream>
#include <fstream>
@ -321,6 +322,12 @@ void initfg(ParserState* pp) {
pp->fg->restart_status = IntVarArray(*(pp->fg), 1);
pp->fg->restart_status[0] = pp->fg->iv[pp->status_idx];
}
if (pp->complete_idx >= 0) {
pp->fg->restart_complete = BoolVarArray(*(pp->fg), 1);
pp->fg->restart_complete[0] = pp->fg->bv[pp->complete_idx];
pp->fg->complete_marker = std::make_shared<bool>(false);
Complete::post(*(pp->fg), pp->fg->restart_complete[0], pp->fg->complete_marker);
}
if (!(pp->int_uniform.empty())) {
pp->fg->int_uniform_var = IntVarArray(*(pp->fg), pp->int_uniform.size());
pp->fg->int_uniform_lb = new int[pp->int_uniform.size()];
@ -1463,6 +1470,8 @@ constraint_item :
std::string cid($2);
if (cid=="status" && $4->a[0]->isIntVar()) {
pp->status_idx = $4->a[0]->getIntVar();
} else if (cid=="complete_reif" && $4->a[0]->isBoolVar()) {
pp->complete_idx = $4->a[0]->getBoolVar();
} else if (cid=="int_lastval" && $4->a[0]->isIntVar() && $4->a[1]->isIntVar()) {
int base0 = getBaseIntVar(pp,$4->a[0]->getIntVar());
int base1 = getBaseIntVar(pp,$4->a[1]->getIntVar());

View File

@ -1621,6 +1621,19 @@ namespace Gecode {
/// Information is provided by a portfolio-based engine
PORTFOLIO
};
/// Reason for restarting
enum RReason {
/// No reason - used for PORTFOLIO
RR_NO,
/// Restarting after initialisation
RR_INIT,
/// Restarting after a solution is found
RR_SOL,
/// Restarting after exhausting search space
RR_CMPL,
/// Restarting after reaching restart limit
RR_LIM
};
protected:
/// Type of information
const Type t;
@ -1628,6 +1641,8 @@ namespace Gecode {
//@{
/// Number of restarts
const unsigned long int r;
/// Reason for restarting
const RReason rr;
/// Number of solutions since last restart
const unsigned long long int s;
/// Number of failures since last restart
@ -1647,6 +1662,7 @@ namespace Gecode {
//@{
/// Constructor for restart-based engine
MetaInfo(unsigned long int r,
RReason rr,
unsigned long long int s,
unsigned long long int f,
const Space* l,
@ -1660,6 +1676,8 @@ namespace Gecode {
//@{
/// Return number of restarts
unsigned long int restart(void) const;
/// Return reason for restarting
RReason reason(void) const;
/// Return number of solutions since last restart
unsigned long long int solution(void) const;
/// Return number of failures since last restart
@ -3079,15 +3097,16 @@ namespace Gecode {
*/
forceinline
MetaInfo::MetaInfo(unsigned long int r0,
RReason rr0,
unsigned long long int s0,
unsigned long long int f0,
const Space* l0,
NoGoods& ng0)
: t(RESTART), r(r0), s(s0), f(f0), l(l0), ng(ng0), a(0) {}
: t(RESTART), r(r0), rr(rr0), s(s0), f(f0), l(l0), ng(ng0), a(0) {}
forceinline
MetaInfo::MetaInfo(unsigned int a0)
: t(PORTFOLIO), r(0), s(0), f(0), l(nullptr), ng(NoGoods::eng), a(a0) {}
: t(PORTFOLIO), r(0), rr(RR_NO), s(0), f(0), l(nullptr), ng(NoGoods::eng), a(a0) {}
forceinline MetaInfo::Type
MetaInfo::type(void) const {
@ -3098,6 +3117,10 @@ namespace Gecode {
assert(type() == RESTART);
return r;
}
forceinline MetaInfo::RReason
MetaInfo::reason(void) const {
return rr;
}
forceinline unsigned long long int
MetaInfo::solution(void) const {
assert(type() == RESTART);

View File

@ -816,6 +816,8 @@ namespace Gecode { namespace Search {
static Stop* fail(unsigned long long int l);
/// Stop if time limit \a l (in milliseconds) has been exceeded
static Stop* time(double l);
/// Stop if restart limit \a l has been exceeded
static Stop* restart(unsigned long long int l);
//@}
};
@ -888,6 +890,25 @@ namespace Gecode { namespace Search {
virtual bool stop(const Statistics& s, const Options& o);
};
/**
* \brief %Stop-object based on number of restarts
* \ingroup TaskModelSearchStop
*/
class GECODE_SEARCH_EXPORT RestartStop : public Stop {
protected:
/// Restart limit
unsigned long long int l;
public:
/// Stop if restart limit \a l is exceeded
RestartStop(unsigned long long int l);
/// Return current limit
unsigned long long int limit(void) const;
/// Set current limit to \a l restarts
void limit(unsigned long long int l);
/// Return true if failure limit is exceeded
virtual bool stop(const Statistics& s, const Options& o);
};
}}
#include <gecode/search/stop.hpp>

View File

@ -97,7 +97,7 @@ namespace Gecode {
} else {
Space* master = m_opt.clone ? s->clone() : s;
Space* slave = master->clone();
MetaInfo mi(0,0,0,nullptr,NoGoods::eng);
MetaInfo mi(0,MetaInfo::RR_INIT,0,0,nullptr,NoGoods::eng);
slave->slave(mi);
e = Search::Seq::rbsengine(master,e_opt.stop,
Search::build<T,E>(slave,e_opt),

View File

@ -60,7 +60,7 @@ namespace Gecode { namespace Search { namespace Seq {
NoGoods& ng = e->nogoods();
// Reset number of no-goods found
ng.ng(0);
MetaInfo mi(stop->m_stat.restart,sslr,e->statistics().fail,last,ng);
MetaInfo mi(stop->m_stat.restart,MetaInfo::RR_SOL,sslr,e->statistics().fail,last,ng);
bool r = master->master(mi);
stop->m_stat.nogood += ng.ng();
if (master->status(stop->m_stat) == SS_FAILED) {
@ -96,7 +96,7 @@ namespace Gecode { namespace Search { namespace Seq {
sslr = 0;
NoGoods& ng = e->nogoods();
ng.ng(0);
MetaInfo mi(stop->m_stat.restart,sslr,e->statistics().fail,last,ng);
MetaInfo mi(stop->m_stat.restart,e->stopped() ? MetaInfo::RR_LIM : MetaInfo::RR_CMPL,sslr,e->statistics().fail,last,ng);
(void) master->master(mi);
stop->m_stat.nogood += ng.ng();
unsigned long long int nl = ++(*co);

View File

@ -51,6 +51,10 @@ namespace Gecode { namespace Search {
Stop::time(double l) {
return new TimeStop(l);
}
Stop*
Stop::restart(unsigned long long int l) {
return new RestartStop(l);
}
/*
@ -82,6 +86,14 @@ namespace Gecode { namespace Search {
return t.stop() > l;
}
/*
* Stopping for restart limit
*
*/
bool
RestartStop::stop(const Statistics& s, const Options&) {
return s.restart > l;
}
}}

View File

@ -107,6 +107,24 @@ namespace Gecode { namespace Search {
t.start();
}
/*
* Stopping for restart limit
*
*/
forceinline
RestartStop::RestartStop(unsigned long long int l0) : l(l0) {}
forceinline unsigned long long int
RestartStop::limit(void) const {
return l;
}
forceinline void
RestartStop::limit(unsigned long long int l0) {
l=l0;
}
}}
// STATISTICS: search-other

View File

@ -21,6 +21,7 @@
],
["--restart-base", "Base for geometric restart sequence", "float", "1.5"],
["--restart-scale", "Scale factor for restart sequence", "int", "250"],
["--restart-limit", "Restart cutoff", "int", "0"],
["--nogoods", "Use no-goods from restarts", "bool", "false"],
["--nogoods-limit", "Depth limit for no-good extraction", "int", "128"]
],