git-subtree-dir: software/gecode_on_replay git-subtree-split: 8051d92b9c89e49cccfbd1c201371580d7703ab4
749 lines
26 KiB
C++
Executable File
749 lines
26 KiB
C++
Executable File
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
/*
|
|
* Main authors:
|
|
* Guido Tack <tack@gecode.org>
|
|
*
|
|
* Contributing authors:
|
|
* Gabriel Hjort Blindell <gabriel.hjort.blindell@gmail.com>
|
|
*
|
|
* Copyright:
|
|
* Guido Tack, 2007-2012
|
|
* Gabriel Hjort Blindell, 2012
|
|
*
|
|
* 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_FLATZINC_HH
|
|
#define GECODE_FLATZINC_HH
|
|
|
|
#include <iostream>
|
|
|
|
#include <gecode/kernel.hh>
|
|
#include <gecode/int.hh>
|
|
#ifdef GECODE_HAS_SET_VARS
|
|
#include <gecode/set.hh>
|
|
#endif
|
|
#ifdef GECODE_HAS_FLOAT_VARS
|
|
#include <gecode/float.hh>
|
|
#endif
|
|
#include <map>
|
|
|
|
/*
|
|
* Support for DLLs under Windows
|
|
*
|
|
*/
|
|
|
|
#if !defined(GECODE_STATIC_LIBS) && \
|
|
(defined(__CYGWIN__) || defined(__MINGW32__) || defined(_MSC_VER))
|
|
|
|
#ifdef GECODE_BUILD_FLATZINC
|
|
#define GECODE_FLATZINC_EXPORT __declspec( dllexport )
|
|
#else
|
|
#define GECODE_FLATZINC_EXPORT __declspec( dllimport )
|
|
#endif
|
|
|
|
#else
|
|
|
|
#ifdef GECODE_GCC_HAS_CLASS_VISIBILITY
|
|
|
|
#define GECODE_FLATZINC_EXPORT __attribute__ ((visibility("default")))
|
|
|
|
#else
|
|
|
|
#define GECODE_FLATZINC_EXPORT
|
|
|
|
#endif
|
|
#endif
|
|
|
|
// Configure auto-linking
|
|
#ifndef GECODE_BUILD_FLATZINC
|
|
#define GECODE_LIBRARY_NAME "FlatZinc"
|
|
#include <gecode/support/auto-link.hpp>
|
|
#endif
|
|
|
|
#include <gecode/driver.hh>
|
|
|
|
#include <gecode/flatzinc/conexpr.hh>
|
|
#include <gecode/flatzinc/ast.hh>
|
|
#include <gecode/flatzinc/varspec.hh>
|
|
#include <array>
|
|
#include <memory>
|
|
|
|
/**
|
|
* \namespace Gecode::FlatZinc
|
|
* \brief Interpreter for the %FlatZinc language
|
|
*
|
|
* The Gecode::FlatZinc namespace contains all functionality required
|
|
* to parse and solve constraint models written in the %FlatZinc language.
|
|
*
|
|
*/
|
|
|
|
namespace Gecode { namespace FlatZinc {
|
|
|
|
/**
|
|
* \brief Output support class for %FlatZinc interpreter
|
|
*
|
|
*/
|
|
class GECODE_FLATZINC_EXPORT Printer {
|
|
private:
|
|
/// Names of integer variables
|
|
std::vector<std::string> iv_names;
|
|
/// Names of Boolean variables
|
|
std::vector<std::string> bv_names;
|
|
#ifdef GECODE_HAS_FLOAT_VARS
|
|
/// Names of float variables
|
|
std::vector<std::string> fv_names;
|
|
#endif
|
|
#ifdef GECODE_HAS_SET_VARS
|
|
/// Names of set variables
|
|
std::vector<std::string> sv_names;
|
|
#endif
|
|
AST::Array* _output;
|
|
void printElem(std::ostream& out,
|
|
AST::Node* ai,
|
|
const Gecode::IntVarArray& iv,
|
|
const Gecode::BoolVarArray& bv
|
|
#ifdef GECODE_HAS_SET_VARS
|
|
,
|
|
const Gecode::SetVarArray& sv
|
|
#endif
|
|
#ifdef GECODE_HAS_FLOAT_VARS
|
|
,
|
|
const Gecode::FloatVarArray& fv
|
|
#endif
|
|
) const;
|
|
void printElemDiff(std::ostream& out,
|
|
AST::Node* ai,
|
|
const Gecode::IntVarArray& iv1,
|
|
const Gecode::IntVarArray& iv2,
|
|
const Gecode::BoolVarArray& bv1,
|
|
const Gecode::BoolVarArray& bv2
|
|
#ifdef GECODE_HAS_SET_VARS
|
|
,
|
|
const Gecode::SetVarArray& sv1,
|
|
const Gecode::SetVarArray& sv2
|
|
#endif
|
|
#ifdef GECODE_HAS_FLOAT_VARS
|
|
,
|
|
const Gecode::FloatVarArray& fv1,
|
|
const Gecode::FloatVarArray& fv2
|
|
#endif
|
|
) const;
|
|
public:
|
|
Printer(void) : _output(nullptr) {}
|
|
void init(AST::Array* output);
|
|
|
|
void print(std::ostream& out,
|
|
const Gecode::IntVarArray& iv,
|
|
const Gecode::BoolVarArray& bv
|
|
#ifdef GECODE_HAS_SET_VARS
|
|
,
|
|
const Gecode::SetVarArray& sv
|
|
#endif
|
|
#ifdef GECODE_HAS_FLOAT_VARS
|
|
,
|
|
const Gecode::FloatVarArray& fv
|
|
#endif
|
|
) const;
|
|
|
|
void printDiff(std::ostream& out,
|
|
const Gecode::IntVarArray& iv1, const Gecode::IntVarArray& iv2,
|
|
const Gecode::BoolVarArray& bv1, const Gecode::BoolVarArray& bv2
|
|
#ifdef GECODE_HAS_SET_VARS
|
|
,
|
|
const Gecode::SetVarArray& sv1, const Gecode::SetVarArray& sv2
|
|
#endif
|
|
#ifdef GECODE_HAS_FLOAT_VARS
|
|
,
|
|
const Gecode::FloatVarArray& fv1,
|
|
const Gecode::FloatVarArray& fv2
|
|
#endif
|
|
) const;
|
|
|
|
|
|
~Printer(void);
|
|
|
|
void addIntVarName(const std::string& n);
|
|
const std::string& intVarName(int i) const { return iv_names[i]; }
|
|
void addBoolVarName(const std::string& n);
|
|
const std::string& boolVarName(int i) const { return bv_names[i]; }
|
|
#ifdef GECODE_HAS_FLOAT_VARS
|
|
void addFloatVarName(const std::string& n);
|
|
const std::string& floatVarName(int i) const { return fv_names[i]; }
|
|
#endif
|
|
#ifdef GECODE_HAS_SET_VARS
|
|
void addSetVarName(const std::string& n);
|
|
const std::string& setVarName(int i) const { return sv_names[i]; }
|
|
#endif
|
|
|
|
void shrinkElement(AST::Node* node,
|
|
std::map<int,int>& iv, std::map<int,int>& bv,
|
|
std::map<int,int>& sv, std::map<int,int>& fv);
|
|
|
|
void shrinkArrays(Space& home,
|
|
int& optVar, bool optVarIsInt,
|
|
Gecode::IntVarArray& iv,
|
|
Gecode::BoolVarArray& bv
|
|
#ifdef GECODE_HAS_SET_VARS
|
|
,
|
|
Gecode::SetVarArray& sv
|
|
#endif
|
|
#ifdef GECODE_HAS_FLOAT_VARS
|
|
,
|
|
Gecode::FloatVarArray& fv
|
|
#endif
|
|
);
|
|
|
|
private:
|
|
Printer(const Printer&);
|
|
Printer& operator=(const Printer&);
|
|
};
|
|
|
|
/**
|
|
* \brief %Options for running %FlatZinc models
|
|
*
|
|
*/
|
|
class FlatZincOptions : public Gecode::BaseOptions {
|
|
protected:
|
|
/// \name Search options
|
|
//@{
|
|
Gecode::Driver::IntOption _solutions; ///< How many solutions
|
|
Gecode::Driver::BoolOption _allSolutions; ///< Return all solutions
|
|
Gecode::Driver::DoubleOption _threads; ///< How many threads to use
|
|
Gecode::Driver::BoolOption _free; ///< Use free search
|
|
Gecode::Driver::DoubleOption _decay; ///< Decay option
|
|
Gecode::Driver::UnsignedIntOption _c_d; ///< Copy recomputation distance
|
|
Gecode::Driver::UnsignedIntOption _a_d; ///< Adaptive recomputation distance
|
|
Gecode::Driver::UnsignedLongLongIntOption _node; ///< Cutoff for number of nodes
|
|
Gecode::Driver::UnsignedLongLongIntOption _fail; ///< Cutoff for number of failures
|
|
Gecode::Driver::DoubleOption _time; ///< Cutoff for time
|
|
Gecode::Driver::DoubleOption _time_limit; ///< Cutoff for time (for compatibility with flatzinc command line)
|
|
Gecode::Driver::IntOption _seed; ///< Random seed
|
|
Gecode::Driver::StringOption _restart; ///< Restart method option
|
|
Gecode::Driver::DoubleOption _r_base; ///< Restart base
|
|
Gecode::Driver::UnsignedIntOption _r_scale; ///< Restart scale factor
|
|
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
|
|
Gecode::Driver::DoubleOption _step; ///< Step option
|
|
//@}
|
|
|
|
/// \name Execution options
|
|
//@{
|
|
Gecode::Driver::StringOption _mode; ///< Script mode to run
|
|
Gecode::Driver::BoolOption _stat; ///< Emit statistics
|
|
Gecode::Driver::StringValueOption _output; ///< Output file
|
|
|
|
#ifdef GECODE_HAS_CPPROFILER
|
|
Gecode::Driver::ProfilerOption _profiler; ///< Use this execution id for the CP-profiler
|
|
#endif
|
|
|
|
//@}
|
|
public:
|
|
/// Constructor
|
|
FlatZincOptions(const char* s)
|
|
: Gecode::BaseOptions(s),
|
|
_solutions("n","number of solutions (0 = all, -1 = one/best)",-1),
|
|
_allSolutions("a", "return all solutions (equal to -n 0)"),
|
|
_threads("p","number of threads (0 = #processing units)",
|
|
Gecode::Search::Config::threads),
|
|
_free("f", "free search, no need to follow search-specification"),
|
|
_decay("decay","decay factor",0.99),
|
|
_c_d("c-d","recomputation commit distance",Gecode::Search::Config::c_d),
|
|
_a_d("a-d","recomputation adaption distance",Gecode::Search::Config::a_d),
|
|
_node("node","node cutoff (0 = none, solution mode)"),
|
|
_fail("fail","failure cutoff (0 = none, solution mode)"),
|
|
_time("time","time (in ms) cutoff (0 = none, solution mode)"),
|
|
_time_limit("t","time (in ms) cutoff (0 = none, solution mode)"),
|
|
_seed("r","random seed",0),
|
|
_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),
|
|
_nogoods("nogoods","whether to use no-goods from restarts",false),
|
|
_nogoods_limit("nogoods-limit","depth limit for no-good extraction",
|
|
Search::Config::nogoods_limit),
|
|
_interrupt("interrupt","whether to catch Ctrl-C (true) or not (false)",
|
|
true),
|
|
_step("step","step distance for float optimization",0.0),
|
|
_mode("mode","how to execute script",Gecode::SM_SOLUTION),
|
|
_stat("s","emit statistics"),
|
|
_output("o","file to send output to")
|
|
|
|
#ifdef GECODE_HAS_CPPROFILER
|
|
,
|
|
_profiler("cp-profiler", "use this execution id and port (comma separated) with CP-profiler")
|
|
#endif
|
|
{
|
|
_mode.add(Gecode::SM_SOLUTION, "solution");
|
|
_mode.add(Gecode::SM_STAT, "stat");
|
|
_mode.add(Gecode::SM_GIST, "gist");
|
|
_restart.add(RM_NONE,"none");
|
|
_restart.add(RM_CONSTANT,"constant");
|
|
_restart.add(RM_LINEAR,"linear");
|
|
_restart.add(RM_LUBY,"luby");
|
|
_restart.add(RM_GEOMETRIC,"geometric");
|
|
|
|
add(_solutions); add(_threads); add(_c_d); add(_a_d);
|
|
add(_allSolutions);
|
|
add(_free);
|
|
add(_decay);
|
|
add(_node); add(_fail); add(_time); add(_time_limit); add(_interrupt);
|
|
add(_seed);
|
|
add(_step);
|
|
add(_restart); add(_r_base); add(_r_scale);
|
|
add(_nogoods); add(_nogoods_limit);
|
|
add(_mode); add(_stat);
|
|
add(_output);
|
|
#ifdef GECODE_HAS_CPPROFILER
|
|
add(_profiler);
|
|
#endif
|
|
}
|
|
|
|
void parse(int& argc, char* argv[]) {
|
|
Gecode::BaseOptions::parse(argc,argv);
|
|
if (_allSolutions.value() && _solutions.value()==-1) {
|
|
_solutions.value(0);
|
|
}
|
|
if (_time_limit.value()) {
|
|
_time.value(_time_limit.value());
|
|
}
|
|
if (_stat.value())
|
|
_mode.value(Gecode::SM_STAT);
|
|
}
|
|
|
|
virtual void help(void) {
|
|
std::cerr << "Gecode FlatZinc interpreter" << std::endl
|
|
<< " - Supported FlatZinc version: " << GECODE_FLATZINC_VERSION
|
|
<< std::endl << std::endl;
|
|
Gecode::BaseOptions::help();
|
|
}
|
|
|
|
int solutions(void) const { return _solutions.value(); }
|
|
bool allSolutions(void) const { return _allSolutions.value(); }
|
|
double threads(void) const { return _threads.value(); }
|
|
bool free(void) const { return _free.value(); }
|
|
unsigned int c_d(void) const { return _c_d.value(); }
|
|
unsigned int a_d(void) const { return _a_d.value(); }
|
|
unsigned long long int node(void) const { return _node.value(); }
|
|
unsigned long long int fail(void) const { return _fail.value(); }
|
|
double time(void) const { return _time.value(); }
|
|
int seed(void) const { return _seed.value(); }
|
|
double step(void) const { return _step.value(); }
|
|
const char* output(void) const { return _output.value(); }
|
|
|
|
Gecode::ScriptMode mode(void) const {
|
|
return static_cast<Gecode::ScriptMode>(_mode.value());
|
|
}
|
|
|
|
double decay(void) const { return _decay.value(); }
|
|
RestartMode restart(void) const {
|
|
return static_cast<RestartMode>(_restart.value());
|
|
}
|
|
void restart(RestartMode rm) {
|
|
_restart.value(rm);
|
|
}
|
|
double restart_base(void) const { return _r_base.value(); }
|
|
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); }
|
|
bool nogoods(void) const { return _nogoods.value(); }
|
|
unsigned int nogoods_limit(void) const { return _nogoods_limit.value(); }
|
|
bool interrupt(void) const { return _interrupt.value(); }
|
|
|
|
#ifdef GECODE_HAS_CPPROFILER
|
|
|
|
int profiler_id(void) const { return _profiler.execution_id(); }
|
|
unsigned int profiler_port(void) const { return _profiler.port(); }
|
|
bool profiler_info(void) const { return true; }
|
|
|
|
#endif
|
|
|
|
void allSolutions(bool b) { _allSolutions.value(b); }
|
|
};
|
|
|
|
class BranchInformation : public SharedHandle {
|
|
public:
|
|
/// Constructor
|
|
BranchInformation(void);
|
|
/// Copy constructor
|
|
BranchInformation(const BranchInformation& bi);
|
|
/// Initialise for use
|
|
void init(void);
|
|
/// Add new brancher information
|
|
void add(BrancherGroup bg,
|
|
const std::string& rel0,
|
|
const std::string& rel1,
|
|
const std::vector<std::string>& n);
|
|
/// Output branch information
|
|
void print(const Brancher& b,
|
|
unsigned int a, int i, int n, std::ostream& o) const;
|
|
#ifdef GECODE_HAS_FLOAT_VARS
|
|
/// Output branch information
|
|
void print(const Brancher& b,
|
|
unsigned int a, int i, const FloatNumBranch& nl,
|
|
std::ostream& o) const;
|
|
#endif
|
|
};
|
|
|
|
/// Uninitialized default random number generator
|
|
GECODE_FLATZINC_EXPORT
|
|
extern Rnd defrnd;
|
|
|
|
class FlatZincSpaceInitData;
|
|
|
|
/**
|
|
* \brief A space that can be initialized with a %FlatZinc model
|
|
*
|
|
*/
|
|
class GECODE_FLATZINC_EXPORT FlatZincSpace : public Space {
|
|
public:
|
|
static long long copies;
|
|
enum Meth {
|
|
SAT, //< Solve as satisfaction problem
|
|
MIN, //< Solve as minimization problem
|
|
MAX //< Solve as maximization problem
|
|
};
|
|
protected:
|
|
/// Initialisation data (only used for posting constraints)
|
|
FlatZincSpaceInitData* _initData;
|
|
/// Number of integer variables
|
|
int intVarCount;
|
|
/// Number of Boolean variables
|
|
int boolVarCount;
|
|
/// Number of float variables
|
|
int floatVarCount;
|
|
/// Number of set variables
|
|
int setVarCount;
|
|
|
|
/// Index of the variable to optimize
|
|
int _optVar;
|
|
/// Whether variable to optimize is integer (or float)
|
|
bool _optVarIsInt;
|
|
|
|
/// Whether to solve as satisfaction or optimization problem
|
|
Meth _method;
|
|
|
|
/// Percentage of variables to keep in LNS (or 0 for no LNS)
|
|
unsigned int _lns;
|
|
|
|
/// Initial solution to start the LNS (or nullptr for no LNS)
|
|
IntSharedArray _lnsInitialSolution;
|
|
|
|
/// Random number generator
|
|
Rnd _random;
|
|
|
|
/// Annotations on the solve item
|
|
AST::Array* _solveAnnotations;
|
|
|
|
/// Copy constructor
|
|
FlatZincSpace(FlatZincSpace&);
|
|
private:
|
|
/// Run the search engine
|
|
template<template<class> class Engine>
|
|
void
|
|
runEngine(std::ostream& out, const Printer& p,
|
|
const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
|
|
/// Run the meta search engine
|
|
template<template<class> class Engine,
|
|
template<class, template<class> class> class Meta>
|
|
void
|
|
runMeta(std::ostream& out, const Printer& p,
|
|
const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
|
|
void
|
|
branchWithPlugin(AST::Node* ann);
|
|
public:
|
|
/// The integer variables
|
|
Gecode::IntVarArray iv;
|
|
/// The introduced integer variables
|
|
Gecode::IntVarArray iv_aux;
|
|
|
|
/// The integer variables used in LNS
|
|
Gecode::IntVarArray iv_lns;
|
|
|
|
/// Status() variable
|
|
Gecode::IntVarArray restart_status;
|
|
/// int_uniform arguments
|
|
Gecode::IntVarArray int_uniform_var;
|
|
int* int_uniform_lb;
|
|
int* int_uniform_ub;
|
|
/// int_sol arguments
|
|
Gecode::IntVarArray int_sol_var;
|
|
Gecode::IntVarArray int_sol_orig;
|
|
/// int_lastval arguments
|
|
Gecode::IntVarArray int_lastval_var;
|
|
std::shared_ptr<int>* int_lastval_val;
|
|
|
|
/// record fixed integers
|
|
static std::ifstream record;
|
|
Gecode::IntVarArray main_vars;
|
|
static std::vector<std::vector<int>> vrecord;
|
|
static size_t record_i;
|
|
|
|
|
|
/// Indicates whether an integer variable is introduced by mzn2fzn
|
|
std::vector<bool> iv_introduced;
|
|
/// Indicates whether an integer variable aliases a Boolean variable
|
|
int* iv_boolalias;
|
|
/// The Boolean variables
|
|
Gecode::BoolVarArray bv;
|
|
/// The introduced Boolean variables
|
|
Gecode::BoolVarArray bv_aux;
|
|
/// Indicates whether a Boolean variable is introduced by mzn2fzn
|
|
std::vector<bool> bv_introduced;
|
|
#ifdef GECODE_HAS_SET_VARS
|
|
/// The set variables
|
|
Gecode::SetVarArray sv;
|
|
/// The introduced set variables
|
|
Gecode::SetVarArray sv_aux;
|
|
/// Indicates whether a set variable is introduced by mzn2fzn
|
|
std::vector<bool> sv_introduced;
|
|
#endif
|
|
#ifdef GECODE_HAS_FLOAT_VARS
|
|
/// The float variables
|
|
Gecode::FloatVarArray fv;
|
|
/// The introduced float variables
|
|
Gecode::FloatVarArray fv_aux;
|
|
/// Indicates whether a float variable is introduced by mzn2fzn
|
|
std::vector<bool> fv_introduced;
|
|
/// Step by which a next solution has to have lower cost
|
|
Gecode::FloatNum step;
|
|
#endif
|
|
/// Whether the introduced variables still need to be copied
|
|
bool needAuxVars;
|
|
/// Construct empty space
|
|
FlatZincSpace(Rnd& random = defrnd);
|
|
|
|
/// Destructor
|
|
~FlatZincSpace(void);
|
|
|
|
/// Initialize space with given number of variables
|
|
void init(int intVars, int boolVars, int setVars, int floatVars);
|
|
|
|
/// Create new integer variable from specification
|
|
void newIntVar(IntVarSpec* vs);
|
|
/// Link integer variable \a iv to Boolean variable \a bv
|
|
void aliasBool2Int(int iv, int bv);
|
|
/// Return linked Boolean variable for integer variable \a iv
|
|
int aliasBool2Int(int iv);
|
|
/// Create new Boolean variable from specification
|
|
void newBoolVar(BoolVarSpec* vs);
|
|
/// Create new set variable from specification
|
|
void newSetVar(SetVarSpec* vs);
|
|
/// Create new float variable from specification
|
|
void newFloatVar(FloatVarSpec* vs);
|
|
|
|
/// Post a constraint specified by \a ce
|
|
void postConstraints(std::vector<ConExpr*>& ces);
|
|
|
|
/// Post the solve item
|
|
void solve(AST::Array* annotation);
|
|
/// Post that integer variable \a var should be minimized
|
|
void minimize(int var, bool isInt, AST::Array* annotation);
|
|
/// Post that integer variable \a var should be maximized
|
|
void maximize(int var, bool isInt, AST::Array* annotation);
|
|
|
|
/// Run the search
|
|
void run(std::ostream& out, const Printer& p,
|
|
const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
|
|
|
|
/// Produce output on \a out using \a p
|
|
void print(std::ostream& out, const Printer& p) const;
|
|
#ifdef GECODE_HAS_CPPROFILER
|
|
/// Get string representing the domains of variables (for cpprofiler)
|
|
std::string getDomains(const Printer& p) const;
|
|
#endif
|
|
/// Compare this space with space \a s and print the differences on
|
|
/// \a out
|
|
void compare(const Space& s, std::ostream& out) const;
|
|
/// Compare this space with space \a s and print the differences on
|
|
/// \a out using \a p
|
|
void compare(const FlatZincSpace& s, std::ostream& out,
|
|
const Printer& p) const;
|
|
|
|
/**
|
|
* \brief Remove all variables not needed for output
|
|
*
|
|
* After calling this function, no new constraints can be posted through
|
|
* FlatZinc variable references, and the createBranchers method must
|
|
* not be called again.
|
|
*
|
|
*/
|
|
void shrinkArrays(Printer& p);
|
|
|
|
/// Return whether to solve a satisfaction or optimization problem
|
|
Meth method(void) const;
|
|
|
|
/// Return index of variable used for optimization
|
|
int optVar(void) const;
|
|
/// Return whether variable used for optimization is integer (or float)
|
|
bool optVarIsInt(void) const;
|
|
|
|
/**
|
|
* \brief Create branchers corresponding to the solve item annotations
|
|
*
|
|
* If \a ignoreUnknown is true, unknown solve item annotations will be
|
|
* ignored, otherwise a warning is written to \a err.
|
|
*
|
|
* The seed for random branchers is given by the \a seed parameter.
|
|
*
|
|
*/
|
|
void createBranchers(Printer& p, AST::Node* ann,
|
|
FlatZincOptions& opt, bool ignoreUnknown,
|
|
std::ostream& err = std::cerr);
|
|
|
|
/// Return the solve item annotations
|
|
AST::Array* solveAnnotations(void) const;
|
|
|
|
/// Information for printing branches
|
|
BranchInformation branchInfo;
|
|
|
|
/// Implement optimization
|
|
virtual void constrain(const Space& s);
|
|
/// Copy function
|
|
virtual Gecode::Space* copy(void);
|
|
/// Slave function for restarts
|
|
virtual bool slave(const MetaInfo& mi);
|
|
|
|
/// \name AST to variable and value conversion
|
|
//@{
|
|
/// Convert \a arg (array of integers) to IntArgs
|
|
IntArgs arg2intargs(AST::Node* arg, int offset = 0);
|
|
/// Convert \a arg (array of integers) to IntSharedArray
|
|
IntSharedArray arg2intsharedarray(AST::Node* arg, int offset = 0);
|
|
/// Convert \a arg (array of Booleans) to IntArgs
|
|
IntArgs arg2boolargs(AST::Node* arg, int offset = 0);
|
|
/// Convert \a arg (array of integers) to IntSharedArray
|
|
IntSharedArray arg2boolsharedarray(AST::Node* arg, int offset = 0);
|
|
/// Convert \a n to IntSet
|
|
IntSet arg2intset(AST::Node* n);
|
|
/// Convert \a arg to IntSetArgs
|
|
IntSetArgs arg2intsetargs(AST::Node* arg, int offset = 0);
|
|
/// Convert \a arg to IntVarArgs
|
|
IntVarArgs arg2intvarargs(AST::Node* arg, int offset = 0);
|
|
/// Convert \a arg to BoolVarArgs
|
|
BoolVarArgs arg2boolvarargs(AST::Node* arg, int offset = 0, int siv=-1);
|
|
/// Convert \a n to BoolVar
|
|
BoolVar arg2BoolVar(AST::Node* n);
|
|
/// Convert \a n to IntVar
|
|
IntVar arg2IntVar(AST::Node* n);
|
|
/// Convert \a a to TupleSet
|
|
TupleSet arg2tupleset(const IntArgs& a, int noOfVars);
|
|
/// Check if \a b is array of Booleans (or has a single integer)
|
|
bool isBoolArray(AST::Node* b, int& singleInt);
|
|
#ifdef GECODE_HAS_SET_VARS
|
|
/// Convert \a n to SetVar
|
|
SetVar arg2SetVar(AST::Node* n);
|
|
/// Convert \a n to SetVarArgs
|
|
SetVarArgs arg2setvarargs(AST::Node* arg, int offset = 0, int doffset = 0,
|
|
const IntSet& od=IntSet::empty);
|
|
#endif
|
|
#ifdef GECODE_HAS_FLOAT_VARS
|
|
/// Convert \a n to FloatValArgs
|
|
FloatValArgs arg2floatargs(AST::Node* arg, int offset = 0);
|
|
/// Convert \a n to FloatVar
|
|
FloatVar arg2FloatVar(AST::Node* n);
|
|
/// Convert \a n to FloatVarArgs
|
|
FloatVarArgs arg2floatvarargs(AST::Node* arg, int offset = 0);
|
|
#endif
|
|
/// Convert \a ann to integer propagation level
|
|
IntPropLevel ann2ipl(AST::Node* ann);
|
|
/// Share DFA \a a if possible
|
|
DFA getSharedDFA(DFA& a);
|
|
//@}
|
|
};
|
|
|
|
/// %Exception class for %FlatZinc errors
|
|
class GECODE_VTABLE_EXPORT Error {
|
|
private:
|
|
const std::string msg;
|
|
public:
|
|
Error(const std::string& where, const std::string& what)
|
|
: msg(where+": "+what) {}
|
|
Error(const std::string& where, const std::string& what, AST::Array *const ann)
|
|
: msg(make_message(where, what, ann)) {}
|
|
const std::string& toString(void) const { return msg; }
|
|
private:
|
|
static std::string make_message(const std::string &where, const std::string &what, AST::Array *const ann) {
|
|
std::ostringstream result;
|
|
result << where << ": " << what;
|
|
|
|
std::vector<std::string> names = get_constraint_names(ann);
|
|
if (names.size() > 1) {
|
|
result << " in constraints ";
|
|
for (unsigned int i = 0; i < names.size(); ++i) {
|
|
result << '\"' << names[i] << '\"';
|
|
if (i < names.size() - 1) {
|
|
result << ",";
|
|
}
|
|
result << " ";
|
|
}
|
|
} else if (names.size() == 1) {
|
|
result << " in constraint " << '\"' << names[0] << '\"';
|
|
}
|
|
|
|
return result.str();
|
|
}
|
|
static std::vector<std::string> get_constraint_names(AST::Array *const ann) {
|
|
std::vector<std::string> result;
|
|
if (ann) {
|
|
for (const auto & i : ann->a) {
|
|
if (i->isArray()) {
|
|
auto nested_result = get_constraint_names(i->getArray());
|
|
result.insert(result.end(), nested_result.begin(), nested_result.end());
|
|
} else if (i->isCall("mzn_constraint_name")) {
|
|
result.emplace_back(i->getCall()->args->getString());
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* \brief Parse FlatZinc file \a fileName into \a fzs and return it.
|
|
*
|
|
* Creates a new empty FlatZincSpace if \a fzs is nullptr.
|
|
*/
|
|
GECODE_FLATZINC_EXPORT
|
|
FlatZincSpace* parse(const std::string& fileName,
|
|
Printer& p, std::ostream& err = std::cerr,
|
|
FlatZincSpace* fzs=nullptr, Rnd& rnd=defrnd);
|
|
|
|
/**
|
|
* \brief Parse FlatZinc from \a is into \a fzs and return it.
|
|
*
|
|
* Creates a new empty FlatZincSpace if \a fzs is nullptr.
|
|
*/
|
|
GECODE_FLATZINC_EXPORT
|
|
FlatZincSpace* parse(std::istream& is,
|
|
Printer& p, std::ostream& err = std::cerr,
|
|
FlatZincSpace* fzs=nullptr, Rnd& rnd=defrnd);
|
|
|
|
}}
|
|
|
|
#endif
|
|
|
|
// STATISTICS: flatzinc-any
|