00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef __GECODE_FLATZINC_HH__
00043 #define __GECODE_FLATZINC_HH__
00044
00045 #include <iostream>
00046
00047 #include <gecode/kernel.hh>
00048 #include <gecode/int.hh>
00049 #ifdef GECODE_HAS_SET_VARS
00050 #include <gecode/set.hh>
00051 #endif
00052 #ifdef GECODE_HAS_FLOAT_VARS
00053 #include <gecode/float.hh>
00054 #endif
00055 #include <map>
00056
00057
00058
00059
00060
00061
00062 #if !defined(GECODE_STATIC_LIBS) && \
00063 (defined(__CYGWIN__) || defined(__MINGW32__) || defined(_MSC_VER))
00064
00065 #ifdef GECODE_BUILD_FLATZINC
00066 #define GECODE_FLATZINC_EXPORT __declspec( dllexport )
00067 #else
00068 #define GECODE_FLATZINC_EXPORT __declspec( dllimport )
00069 #endif
00070
00071 #else
00072
00073 #ifdef GECODE_GCC_HAS_CLASS_VISIBILITY
00074
00075 #define GECODE_FLATZINC_EXPORT __attribute__ ((visibility("default")))
00076
00077 #else
00078
00079 #define GECODE_FLATZINC_EXPORT
00080
00081 #endif
00082 #endif
00083
00084
00085 #ifndef GECODE_BUILD_FLATZINC
00086 #define GECODE_LIBRARY_NAME "FlatZinc"
00087 #include <gecode/support/auto-link.hpp>
00088 #endif
00089
00090 #include <gecode/driver.hh>
00091
00092 #include <gecode/flatzinc/conexpr.hh>
00093 #include <gecode/flatzinc/ast.hh>
00094 #include <gecode/flatzinc/varspec.hh>
00095
00105 namespace Gecode { namespace FlatZinc {
00106
00111 class GECODE_FLATZINC_EXPORT Printer {
00112 private:
00114 std::vector<std::string> iv_names;
00116 std::vector<std::string> bv_names;
00117 #ifdef GECODE_HAS_FLOAT_VARS
00118
00119 std::vector<std::string> fv_names;
00120 #endif
00121 #ifdef GECODE_HAS_SET_VARS
00122
00123 std::vector<std::string> sv_names;
00124 #endif
00125 AST::Array* _output;
00126 void printElem(std::ostream& out,
00127 AST::Node* ai,
00128 const Gecode::IntVarArray& iv,
00129 const Gecode::BoolVarArray& bv
00130 #ifdef GECODE_HAS_SET_VARS
00131 ,
00132 const Gecode::SetVarArray& sv
00133 #endif
00134 #ifdef GECODE_HAS_FLOAT_VARS
00135 ,
00136 const Gecode::FloatVarArray& fv
00137 #endif
00138 ) const;
00139 void printElemDiff(std::ostream& out,
00140 AST::Node* ai,
00141 const Gecode::IntVarArray& iv1,
00142 const Gecode::IntVarArray& iv2,
00143 const Gecode::BoolVarArray& bv1,
00144 const Gecode::BoolVarArray& bv2
00145 #ifdef GECODE_HAS_SET_VARS
00146 ,
00147 const Gecode::SetVarArray& sv1,
00148 const Gecode::SetVarArray& sv2
00149 #endif
00150 #ifdef GECODE_HAS_FLOAT_VARS
00151 ,
00152 const Gecode::FloatVarArray& fv1,
00153 const Gecode::FloatVarArray& fv2
00154 #endif
00155 ) const;
00156 public:
00157 Printer(void) : _output(NULL) {}
00158 void init(AST::Array* output);
00159
00160 void print(std::ostream& out,
00161 const Gecode::IntVarArray& iv,
00162 const Gecode::BoolVarArray& bv
00163 #ifdef GECODE_HAS_SET_VARS
00164 ,
00165 const Gecode::SetVarArray& sv
00166 #endif
00167 #ifdef GECODE_HAS_FLOAT_VARS
00168 ,
00169 const Gecode::FloatVarArray& fv
00170 #endif
00171 ) const;
00172
00173 void printDiff(std::ostream& out,
00174 const Gecode::IntVarArray& iv1, const Gecode::IntVarArray& iv2,
00175 const Gecode::BoolVarArray& bv1, const Gecode::BoolVarArray& bv2
00176 #ifdef GECODE_HAS_SET_VARS
00177 ,
00178 const Gecode::SetVarArray& sv1, const Gecode::SetVarArray& sv2
00179 #endif
00180 #ifdef GECODE_HAS_FLOAT_VARS
00181 ,
00182 const Gecode::FloatVarArray& fv1,
00183 const Gecode::FloatVarArray& fv2
00184 #endif
00185 ) const;
00186
00187
00188 ~Printer(void);
00189
00190 void addIntVarName(const std::string& n);
00191 const std::string& intVarName(int i) const { return iv_names[i]; }
00192 void addBoolVarName(const std::string& n);
00193 const std::string& boolVarName(int i) const { return bv_names[i]; }
00194 #ifdef GECODE_HAS_FLOAT_VARS
00195 void addFloatVarName(const std::string& n);
00196 const std::string& floatVarName(int i) const { return fv_names[i]; }
00197 #endif
00198 #ifdef GECODE_HAS_SET_VARS
00199 void addSetVarName(const std::string& n);
00200 const std::string& setVarName(int i) const { return sv_names[i]; }
00201 #endif
00202
00203 void shrinkElement(AST::Node* node,
00204 std::map<int,int>& iv, std::map<int,int>& bv,
00205 std::map<int,int>& sv, std::map<int,int>& fv);
00206
00207 void shrinkArrays(Space& home,
00208 int& optVar, bool optVarIsInt,
00209 Gecode::IntVarArray& iv,
00210 Gecode::BoolVarArray& bv
00211 #ifdef GECODE_HAS_SET_VARS
00212 ,
00213 Gecode::SetVarArray& sv
00214 #endif
00215 #ifdef GECODE_HAS_FLOAT_VARS
00216 ,
00217 Gecode::FloatVarArray& fv
00218 #endif
00219 );
00220
00221 private:
00222 Printer(const Printer&);
00223 Printer& operator=(const Printer&);
00224 };
00225
00230 class FlatZincOptions : public Gecode::BaseOptions {
00231 protected:
00233
00234 Gecode::Driver::IntOption _solutions;
00235 Gecode::Driver::BoolOption _allSolutions;
00236 Gecode::Driver::DoubleOption _threads;
00237 Gecode::Driver::BoolOption _free;
00238 Gecode::Driver::DoubleOption _decay;
00239 Gecode::Driver::UnsignedIntOption _c_d;
00240 Gecode::Driver::UnsignedIntOption _a_d;
00241 Gecode::Driver::UnsignedIntOption _node;
00242 Gecode::Driver::UnsignedIntOption _fail;
00243 Gecode::Driver::UnsignedIntOption _time;
00244 Gecode::Driver::IntOption _seed;
00245 Gecode::Driver::StringOption _restart;
00246 Gecode::Driver::DoubleOption _r_base;
00247 Gecode::Driver::UnsignedIntOption _r_scale;
00248 Gecode::Driver::BoolOption _nogoods;
00249 Gecode::Driver::UnsignedIntOption _nogoods_limit;
00250 Gecode::Driver::BoolOption _interrupt;
00251 Gecode::Driver::DoubleOption _step;
00252
00253
00255
00256 Gecode::Driver::StringOption _mode;
00257 Gecode::Driver::BoolOption _stat;
00258 Gecode::Driver::StringValueOption _output;
00259
00260 public:
00262 FlatZincOptions(const char* s)
00263 : Gecode::BaseOptions(s),
00264 _solutions("-n","number of solutions (0 = all, -1 = one/best)",-1),
00265 _allSolutions("-a", "return all solutions (equal to -n 0)"),
00266 _threads("-p","number of threads (0 = #processing units)",
00267 Gecode::Search::Config::threads),
00268 _free("-f", "free search, no need to follow search-specification"),
00269 _decay("-decay","decay factor",0.99),
00270 _c_d("-c-d","recomputation commit distance",Gecode::Search::Config::c_d),
00271 _a_d("-a-d","recomputation adaption distance",Gecode::Search::Config::a_d),
00272 _node("-node","node cutoff (0 = none, solution mode)"),
00273 _fail("-fail","failure cutoff (0 = none, solution mode)"),
00274 _time("-time","time (in ms) cutoff (0 = none, solution mode)"),
00275 _seed("-r","random seed",0),
00276 _restart("-restart","restart sequence type",RM_NONE),
00277 _r_base("-restart-base","base for geometric restart sequence",1.5),
00278 _r_scale("-restart-scale","scale factor for restart sequence",250),
00279 _nogoods("-nogoods","whether to use no-goods from restarts",false),
00280 _nogoods_limit("-nogoods-limit","depth limit for no-good extraction",
00281 Search::Config::nogoods_limit),
00282 _interrupt("-interrupt","whether to catch Ctrl-C (true) or not (false)",
00283 true),
00284 _step("-step","step distance for float optimization",0.0),
00285 _mode("-mode","how to execute script",Gecode::SM_SOLUTION),
00286 _stat("-s","emit statistics"),
00287 _output("-o","file to send output to") {
00288
00289 _mode.add(Gecode::SM_SOLUTION, "solution");
00290 _mode.add(Gecode::SM_STAT, "stat");
00291 _mode.add(Gecode::SM_GIST, "gist");
00292 _restart.add(RM_NONE,"none");
00293 _restart.add(RM_CONSTANT,"constant");
00294 _restart.add(RM_LINEAR,"linear");
00295 _restart.add(RM_LUBY,"luby");
00296 _restart.add(RM_GEOMETRIC,"geometric");
00297
00298 add(_solutions); add(_threads); add(_c_d); add(_a_d);
00299 add(_allSolutions);
00300 add(_free);
00301 add(_decay);
00302 add(_node); add(_fail); add(_time); add(_interrupt);
00303 add(_seed);
00304 add(_step);
00305 add(_restart); add(_r_base); add(_r_scale);
00306 add(_nogoods); add(_nogoods_limit);
00307 add(_mode); add(_stat);
00308 add(_output);
00309 }
00310
00311 void parse(int& argc, char* argv[]) {
00312 Gecode::BaseOptions::parse(argc,argv);
00313 if (_allSolutions.value() && _solutions.value()==-1) {
00314 _solutions.value(0);
00315 }
00316 if (_stat.value())
00317 _mode.value(Gecode::SM_STAT);
00318 }
00319
00320 virtual void help(void) {
00321 std::cerr << "Gecode FlatZinc interpreter" << std::endl
00322 << " - Supported FlatZinc version: " << GECODE_FLATZINC_VERSION
00323 << std::endl << std::endl;
00324 Gecode::BaseOptions::help();
00325 }
00326
00327 int solutions(void) const { return _solutions.value(); }
00328 bool allSolutions(void) const { return _allSolutions.value(); }
00329 double threads(void) const { return _threads.value(); }
00330 bool free(void) const { return _free.value(); }
00331 unsigned int c_d(void) const { return _c_d.value(); }
00332 unsigned int a_d(void) const { return _a_d.value(); }
00333 unsigned int node(void) const { return _node.value(); }
00334 unsigned int fail(void) const { return _fail.value(); }
00335 unsigned int time(void) const { return _time.value(); }
00336 int seed(void) const { return _seed.value(); }
00337 double step(void) const { return _step.value(); }
00338 const char* output(void) const { return _output.value(); }
00339 Gecode::ScriptMode mode(void) const {
00340 return static_cast<Gecode::ScriptMode>(_mode.value());
00341 }
00342
00343 double decay(void) const { return _decay.value(); }
00344 RestartMode restart(void) const {
00345 return static_cast<RestartMode>(_restart.value());
00346 }
00347 double restart_base(void) const { return _r_base.value(); }
00348 unsigned int restart_scale(void) const { return _r_scale.value(); }
00349 bool nogoods(void) const { return _nogoods.value(); }
00350 unsigned int nogoods_limit(void) const { return _nogoods_limit.value(); }
00351 bool interrupt(void) const { return _interrupt.value(); }
00352
00353 void allSolutions(bool b) { _allSolutions.value(b); }
00354 };
00355
00356 class BranchInformation : public SharedHandle {
00357 public:
00359 BranchInformation(void);
00361 BranchInformation(const BranchInformation& bi);
00363 void init(void);
00365 void add(BrancherGroup bg,
00366 const std::string& rel0,
00367 const std::string& rel1,
00368 const std::vector<std::string>& n);
00370 void print(const Brancher& b,
00371 unsigned int a, int i, int n, std::ostream& o) const;
00372 #ifdef GECODE_HAS_FLOAT_VARS
00373
00374 void print(const Brancher& b,
00375 unsigned int a, int i, const FloatNumBranch& nl,
00376 std::ostream& o) const;
00377 #endif
00378 };
00379
00384 class GECODE_FLATZINC_EXPORT FznRnd {
00385 protected:
00387 Gecode::Support::RandomGenerator random;
00389 Gecode::Support::Mutex mutex;
00390 public:
00392 FznRnd(unsigned int s=1);
00394 unsigned int operator ()(unsigned int n);
00395 };
00396
00401 class GECODE_FLATZINC_EXPORT FlatZincSpace : public Space {
00402 public:
00403 enum Meth {
00404 SAT,
00405 MIN,
00406 MAX
00407 };
00408 protected:
00410 int intVarCount;
00412 int boolVarCount;
00414 int floatVarCount;
00416 int setVarCount;
00417
00419 int _optVar;
00421 bool _optVarIsInt;
00422
00424 Meth _method;
00425
00427 unsigned int _lns;
00428
00430 IntSharedArray _lnsInitialSolution;
00431
00433 FznRnd* _random;
00434
00436 AST::Array* _solveAnnotations;
00437
00439 FlatZincSpace(bool share, FlatZincSpace&);
00440 private:
00442 template<template<class> class Engine>
00443 void
00444 runEngine(std::ostream& out, const Printer& p,
00445 const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
00447 template<template<class> class Engine,
00448 template<class, template<class> class> class Meta>
00449 void
00450 runMeta(std::ostream& out, const Printer& p,
00451 const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
00452 void
00453 branchWithPlugin(AST::Node* ann);
00454 public:
00456 Gecode::IntVarArray iv;
00458 Gecode::IntVarArray iv_aux;
00459
00461 Gecode::IntVarArray iv_lns;
00462
00464 std::vector<bool> iv_introduced;
00466 int* iv_boolalias;
00468 Gecode::BoolVarArray bv;
00470 Gecode::BoolVarArray bv_aux;
00472 std::vector<bool> bv_introduced;
00473 #ifdef GECODE_HAS_SET_VARS
00474
00475 Gecode::SetVarArray sv;
00477 Gecode::SetVarArray sv_aux;
00479 std::vector<bool> sv_introduced;
00480 #endif
00481 #ifdef GECODE_HAS_FLOAT_VARS
00482
00483 Gecode::FloatVarArray fv;
00485 Gecode::FloatVarArray fv_aux;
00487 std::vector<bool> fv_introduced;
00489 Gecode::FloatNum step;
00490 #endif
00491
00492 bool needAuxVars;
00494 FlatZincSpace(FznRnd* random = NULL);
00495
00497 ~FlatZincSpace(void);
00498
00500 void init(int intVars, int boolVars, int setVars, int floatVars);
00501
00503 void newIntVar(IntVarSpec* vs);
00505 void aliasBool2Int(int iv, int bv);
00507 int aliasBool2Int(int iv);
00509 void newBoolVar(BoolVarSpec* vs);
00511 void newSetVar(SetVarSpec* vs);
00513 void newFloatVar(FloatVarSpec* vs);
00514
00516 void postConstraints(std::vector<ConExpr*>& ces);
00517
00519 void solve(AST::Array* annotation);
00521 void minimize(int var, bool isInt, AST::Array* annotation);
00523 void maximize(int var, bool isInt, AST::Array* annotation);
00524
00526 void run(std::ostream& out, const Printer& p,
00527 const FlatZincOptions& opt, Gecode::Support::Timer& t_total);
00528
00530 void print(std::ostream& out, const Printer& p) const;
00531
00534 void compare(const Space& s, std::ostream& out) const;
00537 void compare(const FlatZincSpace& s, std::ostream& out,
00538 const Printer& p) const;
00539
00548 void shrinkArrays(Printer& p);
00549
00551 Meth method(void) const;
00552
00554 int optVar(void) const;
00556 bool optVarIsInt(void) const;
00557
00567 void createBranchers(Printer& p, AST::Node* ann,
00568 int seed, double decay,
00569 bool ignoreUnknown,
00570 std::ostream& err = std::cerr);
00571
00573 AST::Array* solveAnnotations(void) const;
00574
00576 BranchInformation branchInfo;
00577
00579 virtual void constrain(const Space& s);
00581 virtual Gecode::Space* copy(bool share);
00583 virtual bool slave(const MetaInfo& mi);
00584
00586
00587
00588 IntArgs arg2intargs(AST::Node* arg, int offset = 0);
00590 IntArgs arg2boolargs(AST::Node* arg, int offset = 0);
00592 IntSet arg2intset(AST::Node* n);
00594 IntSetArgs arg2intsetargs(AST::Node* arg, int offset = 0);
00596 IntVarArgs arg2intvarargs(AST::Node* arg, int offset = 0);
00598 BoolVarArgs arg2boolvarargs(AST::Node* arg, int offset = 0, int siv=-1);
00600 BoolVar arg2BoolVar(AST::Node* n);
00602 IntVar arg2IntVar(AST::Node* n);
00604 bool isBoolArray(AST::Node* b, int& singleInt);
00605 #ifdef GECODE_HAS_SET_VARS
00606
00607 SetVar arg2SetVar(AST::Node* n);
00609 SetVarArgs arg2setvarargs(AST::Node* arg, int offset = 0, int doffset = 0,
00610 const IntSet& od=IntSet::empty);
00611 #endif
00612 #ifdef GECODE_HAS_FLOAT_VARS
00613
00614 FloatValArgs arg2floatargs(AST::Node* arg, int offset = 0);
00616 FloatVar arg2FloatVar(AST::Node* n);
00618 FloatVarArgs arg2floatvarargs(AST::Node* arg, int offset = 0);
00619 #endif
00620
00621 IntPropLevel ann2ipl(AST::Node* ann);
00623 };
00624
00626 class GECODE_VTABLE_EXPORT Error {
00627 private:
00628 const std::string msg;
00629 public:
00630 Error(const std::string& where, const std::string& what)
00631 : msg(where+": "+what) {}
00632 const std::string& toString(void) const { return msg; }
00633 };
00634
00640 GECODE_FLATZINC_EXPORT
00641 FlatZincSpace* parse(const std::string& fileName,
00642 Printer& p, std::ostream& err = std::cerr,
00643 FlatZincSpace* fzs=NULL, FznRnd* rnd=NULL);
00644
00650 GECODE_FLATZINC_EXPORT
00651 FlatZincSpace* parse(std::istream& is,
00652 Printer& p, std::ostream& err = std::cerr,
00653 FlatZincSpace* fzs=NULL, FznRnd* rnd=NULL);
00654
00655 }}
00656
00657 #endif
00658
00659